美文网首页
Python基础

Python基础

作者: fuadon | 来源:发表于2017-10-15 22:30 被阅读0次

    基于Python2.7学习

    (一)概述

    一、为什么学Python

    1. 语法简单,易上手;
    2. 丰富的库支持,对Json支持,http、ftp、file、进程等;
    3. 完整的生态圈,一切皆有可能(大数据,云计算,自动化运维等常见);

    结合unix-shell和C的使用习惯,在2000年发布2.0实现垃圾回收和Unicode支持。

    二、特点

    • 免费开源
    • 动态数据类型,高层语言(没有类型检查)
    • 可移植行,个别模块跟操作系统os有关
    • 面向对象
    • 可扩展性,底层用C实现
    • 丰富的标准库

    三、生态圈

    • 不同解释器支持
    • web应用开发
    • 科学计算与大数据分析
    • 云计算

    几种解释器:

    • Cpython解释器:C语言实现,常见解释器;
    • Jython解释器:JVM,Java库;
    • IronPython:.NET
    • pypy:基于JIT的python解释器,即时编译;

    四、Python web开发框架

    • Django,最流行和成熟的web开发框架
    • Tornado,Facebook开发的高性能web服务
    • Uliueb,国人开发的web框架
    • Flask

    五、Python社区
    华蟒用户组,中文社区
    啄木鸟社区
    豆瓣Python小组

    六、安装Django

    pip install django --index-url=http://pypi.douban.com/simple
    python manage.py install
    

    (二)Python基础

    一、Python参数传递
    参数传递顺序依次:

    • 位置参数传递
    • 关键字传递
    • 表传递(列表)
    • 字典传递

    位置参数传递:值传递;
    关键字传递:根据每个参数的名字传递;
    表传递:表传递给函数的是一个指针,指针指向序列在内存中的位置;
    字典传递:包裹传参;

    例如:

    def f(a, b=None, c=3, *args, **kwargs):
        pass
    

    混合传参顺序:先位置,再关键字,再包裹位置,再包裹关键字;
    关键字传参与位置传参混用时,位置传参须在关键字传参之前;

    def foo(name, count=1, *args, **kwargs):
        print name
        print count
        print args
        print kwargs
    foo("python", 12, *(13,14,15), **{'a':1, 'b':2})
    foo("python", *(13,14,15), **{'a':1, 'b':2})
    

    二、MVT架构

    MVT架构

    三、Django框架

    1. 包管理器安装
    pip install django --index-url http://pypi.douban.com/simple
    

    仓库:

    http://pypi.douban.com/simple  # 豆瓣python模块镜像
    http://pypi.python.org/pypi    # 中央仓库
    
    1. 从源码安装
      下载Django的压缩包并解压;然后执行:
    python setup.py install
    
    1. 创建第一个Django的project
    django-admin.py startproject [projname]
    

    项目目录结构:

    manage.py  # Django应用的管理工具
    project/
        settings.py  # 整个项目的核心配置文件,数据库、缓存、session等
        urls.py  # URL转发的配置文件
        wsgi.py
    

    manage.py:管理Django项目命令行工具,支持多个命令,支持扩展自定义的命令,创建数据库schema,启动内嵌的应用服务器;

    python manage.py [subcomand]
    python manage.py help
    

    settings.py:整个项目的核心配置文件

    • 数据库的连接信息
    • 缓存配置
    • session配置
    • 静态文件配置,比如:css、js
    • 用户自定义信息

    运行app:

    python manage.py startapp [app name]
    
    1. ORM
    • Django原生支持关系映射;
    • 每个APP的models.py里面包含了schema的信息;
    • 每次启动项目的时候,都会去验证models.py中的schema和数据库中表对应结构的一致性;
    • 通过python manage.py syncdb来创建表;

    model类:
    每个model类表示一张表,生成的数据库表的名字默认是APP的名字_类的名字
    每个model类里面都有多个Filed的Instance变量;

    primary key:
    默认情况下每个Model类,Django都会自动添加一个id的Integer Field变量作为主键;
    用户也可以自己指定pk字段,默认就可以;

    Query:

    [Model Class].Objects.get()
    eg. Blog.Objects.get(pk=1)
    [Model Class].Objects.[filter/exclude] # 根据特定条件筛选记录
    [Model Class].Objects.all()  # 返回表中的全部数据
    

    QuerySet:
    Filter/exclude/all :三个API返回都是一个QuerySet的对象;
    QuerySet :可以理解为Model实例的集合;
    Lazy Mode :真正Query时查询,不是时时查询;

    QuerySet in Chain :

    Blog.Objects.all().filter(count_it=10)
    

    ORM缺陷:
    需要先手工创建一个空的数据库,无法更新schema的变量;第三方解决http://south.aeracode.org/,自Django1.7+,migration被构建到Django核心模块中,可以使用migration工具迁移schema,更新数据库。

    1. URL与视图的映射
    • 无参数的映射
    url(r'^test/$', get_blog_view)
    
    • 带位置参数的映射
    url(r'^(\d{4})/$', get_blog_view)
    def get_blog_view(req, bid):
        pass
    
    • 关键字参数的映射
    url(r'^(?P<blog id>\d{4})/$', get_blog_view)
    def get_blog_view(req, blogid):
        pass
    

    URL采用最先匹配原则,匹配范围大的URL放在最后。

    1. Template
      {...} 变量
      {% ... %} 模板标签
      {% IF %} ... {% END IF %}
      {% FOR %} ... {% END FOR %}

    模板上下文:
    视图函数返回一个模板的时候,需要传入一个上下文(Context),Context是一个字典,key表示的是模板中的变量名字,value表示渲染完成后实际展示在HTML中的内容。

    def ament_datetime(request):
        now = datetime.datetime.now()
        return render_to_response('current_datetime.html', {'current_date': now})
    

    模板继承:
    css、HEADER、FOOTER写一次,其他模块可用
    通过Block ... Extend继承

    静态文件处理:
    JS、CSS等静态文件的请求处理,settings.py中的STATIC变量指定了静态文件的根目录。

    四、Python语法

    1. 编写脚本文件在第一行添加代码
    #!/usr/bin/python
    #!/usr/local/bin/python
    

    在第二行添加:

    # coding:utf8
    #-*- coding:utf8 -*-
    
    1. 链式赋值:
    a, b = "django", 2
    

    python不支持A++,A--操作;
    Python3:只支持长整型;
    切片操作:slice
    布尔值:True ,False
    dict[key] 查找,效率为O(1)
    字典中key唯一,可以Hash的值。
    dict[key]查找,也可以用key in dict方式来判断字典是否包含key的键。

    1. 循环语句
    for ... :
      ...
    else:
      ...
    

    当for, while正常循环退出时,会执行else语句;当for, while非正常退出时,不会执行else语句;
    非正常退出,相当于break

    try ... :
      ...
    except _, e:
      ...
    except e2:
      ...
    else:
      ...
    finally:
      ...
    

    不抛异常时,执行else语句

    1. Python多重继承
    Class A(ParentA, ParentB, ...):
        pass
    

    __init__是Class构造函数,用来初始化对象

    isDuplicate(s)  # s是一个字符串,是否含有重复的字符
    isPalindrome(s)  # s是一个字符串,字符串是否是回文
    
    1. 搜索路径
      Python会在以下路径中搜索他想要的寻找的模块:
    • 程序所在文件夹
    • 标准库的安装路径
    • 操作系统环境变量PYTHONPATH所包含的路径
    1. Python解释器负责内存管理
      id():返回对象的内存地址
      引用计数为0时,GC才回收内存
      整型缓冲池:整型数据被放到一个缓冲池中
    a=1
    b=1
    

    id(a)与id(b)一样,用来判断是否为同一对象。
    is:用来判断两个变量是不是指向同一个内存对象
    python缓存整数和短字符串,因此每个对象只存有一份,所有整数的引用都指向同一个对象。即使使用赋值语句,也只是创造了新的引用,而不是对象本身。

    1. 包管理器
      pip是Python自带的包管理程序
    pip install web.py
    pip uninstall web.py
    pip install --upgrade web.py
    which python  # 查看Python安装路径
    whereis python # 查看Python安装路径
    pip install --install-option="--prefix=/home/vamei/util/" web.py  # 模块安装路径:/home/vamei/util/
    
    1. global
    def func1():
        global i
        global lock
    if __name__ == "__main__":
        i = 100
        lock = threading.Lock()
        func1()
    

    在函数中使用global声明全局变量;i、lock为不可变数据对象,被当作一个局部变量,所以用global声明;
    对于可变数据对象,则不需要global声明;可以将可变数据对象作为参数来传递给线程函数,这些线程将共享这些可变数据对象。

    1. 线程
      在UNIX平台上,当某个进程终结之后,该进程需要被其父进程调用wait,否则进程成为僵尸进程(Zombie),所以有必要对每个process对象调用join()方法(实际上等同于wait)。对于多线程来说,由于只有一个进程,所以不存在此必要性。
      多线程,可以使用共享资源,比如使用全局变量或传递参数。
      多进程应避免共享资源,每个进程有自己独立的内存空间,可以通过共享内存和Manager的方法共享资源。
    2. 列表解析
      列表解析比for循环性能好很多
    [expr for iter in iterable [if condition]]   # 列表解析
    

    filter(function, iter):用来对列表中的元素进行过滤,function返回false时,该元素就被丢弃。
    map(function, iter):把function(x)作用于列表的每一个元素,然后函数的结果根据顺序构成一个新的列表返回。

    列表解析缺点:
    内存使用效率较低,每次都要把被操作的列表中的元素一次性装载到内存里。
    另一个解决方案:生成器表达式

    • 每次只加载一个元素到内存中
    • 返回一个可迭代的对象
    1. 生成器表达式
    (expr for iter in iterable [if condition])  # 返回generator对象
    res = (expr for iter in iteralbe [if condition])
    for i in res:
        print i
    

    对内存要求较高时,使用生成器表达式
    返回范围较大的列表时用xrange

    1. 字典和集合
      字典:任何一个可以被Hash的数据类型都可以用作key;字典是无序的,值可以是任意数据类型;基于Hash表实现。
      类实例做key,需要类实现__hash__方法返回哈希值。
      列表不可以做key,字典本身不能做key
      元组可以做key,但要求元组中不包含列表、字典等可变类型的数据结构。
      使用hash()函数来检查是否可以用作key
      字符串可以做key
    d = {'a':1, 'b':2}
    d = dict(a=1, b=2)
    d.get('c', 'Default')  # 若字典中没有key为c,则返回默认值Default
    d.keys()  # 返回已存在的key的可迭代对象
    if 'a' in d:
      print e.get('a')    # 使用in判断key是否在字典中
    

    集合:元素不可重复,一组无序排列的可哈希的值,支持Union、intersection等。
    set:可变集合,值是可哈希的
    frozenset:不可变集合
    in:判断是否存在,for:遍历
    集合操作函数:
    更新集合:add、remove、update
    高级操作:

    • union:联合(|)
    • intersection:交集(&)
    • difference:差集(-)
    • symmetric_difference:异或(^)

    五、函数式编程

    1. 函数对象
    def foo():
        pass
    

    foo:函数对象
    foo():函数调用

    a = foo
    a()  # 等价函数调用foo()
    

    不支持重载,在同一模块中定义相同名字的函数,无论参数个数,后定义的一个会覆盖之前的那个。
    可以返回多个值,以元组形式返回,也可以用多个变量接收返回的多个值。

    1. lambda
      返回可调用的函数对象
      不需要return来返回结果
      函数声明和定义均在一行
    foo = lambda x : x+1 if x > 10 else x - 10
    foo(1)
    
    1. 变量查找顺序
    • 局部作用域
    • 全局作用域
    • global关键字
    1. 闭包
    def fx(x):
        def gy(y):
            return x + y
        return gy
    foo = fx(5)
    print foo(10)    # 结果15
    

    装饰器:被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理、Web权限校验、Cache等。

    • 无参数decorator
      生成一个新的装饰器函数
    • 有参decorator
      有参装饰,装饰函数先处理参数,再生成一个新的装饰器函数,然后对函数进行装饰。
    1. 面向对象编程
      特征:
    • 抽象/实现
    • 封装/接口
    • 合成
    • 派生/继承
    • 多态
    • 自省/反射
    class A():    # 经典类
        pass
    class B(object):  # 新式类
        pass
    

    建议使用新式类,新式类必须有一个父类;
    可使用type()测试,type(A)和type(B)
    type(A):返回<type 'classobj'>
    type(B):返回<type 'type'>
    调用父类的__init__方法:

    A.__init__(self)  # 经典类
    super(B, self).__init__()
    

    实例方法:
    方法定义在类中,第一个位置参数为self,self表示实例对象的本省,只能被实例所调用;在调用实例方法时,不需显示地传入self,解释器默认传入。
    Python构造函数:__init__,但不是真正的构造函数,不会创建对象。
    使用__new__来构造对象
    使用__init__来初始化对象
    当使用A()创建实例时,默认使用__init__方法初始化对象。
    类变量和实例变量:
    类变量绑定在类上,实例共享;实例变量绑定在实例对象上,通常使用self.x来表示实例变量。给实例对象赋值时,默认创建实例变量;在查找时,先查找对象本身的属性实例变量,再查找类的属性类变量。

    class A(object):
        author = "Guido"
        def __init__(self, page):
            self.page = page
    book_a = A(10)
    book_b = A(100)
    book_a.author = "python"
    print book_a.author    # 输出"python",author作为book_a的实例变量
    print book_b.author    # 输出"Guido",没有赋值,使用类变量,可用id()检查
    
    1. 类方法和静态方法
      类方法的第一个位置参数不是self,而是cls,表示绑定到类上。
      使用@staticmethod来装饰一个静态方法,静态方法不需要self和cls。
      使用@classmethod来装饰一个类函数。

    类方法:

    @classmethod
    def class_method(cls):
        pass
    

    静态方法:

    @staticmethod
    def static_method(msg):
        print "[" + msg + "]"
    

    子类若没有自己定义__init__方法,会默认调用基类的__init__方法;
    若子类定义了__init__方法,则需要显式调用基类的__init__方法,并且传入self参数;
    super():只工作在新式类
    dir() :查看对象所有属性和方法
    __dict__:类的字典属性
    __doc__:类的文档属性
    __new__:类函数,构造对象
    __init__:初始化对象
    __del__:当对象的引用计数为0时,自动调用,释放内存,要首先调用基类的__del__
    __X:定义private变量,只有类的内部可以引用
    对于实例对象不存在的属性进行赋值,会动态创建这个属性,新式类可以通过设定__slot__的类属性来防止这个问题。

    issubclass(sub, sup)  # 判断是否为子类
    isinstance(obj, classType)  # 判断是否为类的实例
    

    super(A, self) 返回Instance
    super(A, cls) 返回type

    1. 单元测试
    • nose
    • pytest
      namespace:相当于字典
      模块中的变量相当于单例模式
      hashcod要求唯一,计算下标
    1. Python单例模式
    class A(object):
        instance = None
        def __new__(cls, *args, **kwargs):
            if not cls.instance:
                cls.instance = object.__new__(cls, *args, **kwargs)
                return cls.instance
    print id(A())
    print id(A())    # 值相同
    
    1. python常用模块
      模块文档API:
      https://docs.python.org/2/library/
      使用场景:
    • 操作系统相关
    • 文件路径处理
    • 网络处理
    • 数据处理
      os.path模块:处理文件路径
    os.path.join("/a", "b", "c", "d.txt")
    __file__  # 获取当前文件/模块的路径
    

    os模块:

    • 系统环境变量
    • Linux系统上的文件处理
    • 进程处理

    os.environ:可以改环境变量
    sys:获取传入给程序的外部参数argv,进程的输入输出流sys.stdout,sys.stdin环境信息相关。

    import sys
    sys.executable    #判断程序运行的环境
    

    Python从外部获取的参数为字符串。

    # 重定向stdout
    _back = sys.stdout
    f = open("txt.txt", "w")
    sys.stdout = f
    print "kkk"
    f.close()
    

    sys.platform:查看程序运行在什么平台
    subprocess:

          Popen:用来创建子进程
    

    网络相关:

    • urllib
    • httplib

    数据处理:

    • xml模块
    • json模块

    六、virtualenv和virtualenvwrapper

    1. virtualenv
    pip install virtualenv
    pip freeze
    pip freeze | wc -l   # 统计安装的模块
    virtualenv ENV    # 创建一个virtualenv的一个虚拟环境ENV
    source ./ENV/bin/activate  # 启动ENV
    deactivate    # 离开virtualenv环境
    which python    # 查看Python可执行文件的路径
    

    所有安装在系统范围内的包对于virtualenv是可见的,这意味着若将simplejson安装在系统Python目录中,它会自动提供给所有的virtualenv使用。这种行为可以被更改,在创建virtualenv时增加--no-site-packages选项的virtualenv就不会读取系统包,例如:virtualenv ENV --no-site-package

    1. virtualenvwrapper

    建立在virtualenv上的工具,通过它可以方便的创建/激活/管理/销毁虚拟环境。

    workon ENV    # 启用ENV
    workon       # 列出所有虚拟环境
    mkvirtualenv  ENV    # 创建
    workon ENV
    rmvirtualenv  ENV
    

    七、回顾

    1. 当应用计数为0时,GC回收变量占用的 内存;
      del 变量名:删除变量,释放占用的内存;
      is语句:用来判断两个变量是不是指向同一个内存对象;
    2. 声明编码格式,支持中文
    # coding:utf8  或
    # -*- coding:utf8 -*-    # 一般放在第二行
    #!/usr/bin/python    # 放在第一行
    
    1. built-in类型
    • 数值类型
    • 布尔类型
    • 序列类型
    • 集合类型
    • 映射类型
    1. python模块
      Python程序由多个模块文件组成,模块是程序执行的唯一入口;模块是可以被其他模块导入,模块文件为文件名。
    • 模块执行最简单方法
    python [module].py
    #! /usr/bin/python      # 当前python解释器
    
    • 也可以使用./module.py来调用

    模块中定义了什么:

    • 变量[模块级别]
    • 函数的定义
    • 类的定义
    • 程序的实际调用逻辑
    1. 数据类型
      使用弱类型
    • built-in类型
    • 自定义的类型(类,integer)

    变量名字大小写敏感,以下划线、数字、字母命名,以下划线、字母开头;
    支持多个变量的同时定义,简化代码编写:
    a, b = 'django', 2
    数据类型:

    • 整型:32/64 bit,在python3已移除
    • 长整型:没有长度限制,受内存大小限制
    • 浮点型
    • 复数类型
    /  # 普通除法,两个均为整数时,四舍五入;为浮点数时,结果为浮点数;
    //  # 地板除,只保留整数部分
    

    空列表、空元组、空字符串、0均表示False

    对象三要素:

    • identity(身份),对应于内存地址,不可修改
    • type(类型),不可修改
    • value(值),immutable不可修改和mutable可修改

    list | tuple | string正负下标表示:

    • 正:0,1,2,...,n-1
    • 负:-n,-n-1,...,-2,-1

    list支持extend操作,支持原地修改
    [list].extend([list])
    list(), tuple():创建了一个新的序列对象
    字符串是不可变序列,任何一点修改都会创建新的字符串对象。每次'+'操作都会生成一个新的字符串对象。
    "".join(序列)
    拷贝:

    • 浅拷贝:list,tuple工厂函数;切片;copy模块的copy函数;
      浅拷贝不会生成一个新的 序列,指向同一个列表。
    • 深拷贝:生成一个新的序列
    import copy
    c = copy.deepcopy(a)
    

    Tips:持续更新。。。

    相关文章

      网友评论

          本文标题:Python基础

          本文链接:https://www.haomeiwen.com/subject/gnqdyxtx.html