• Python学习笔记


    【Python解释器:】
    CPython:官方默认解释器,使用C语言开发的,命令行中使用该版本的解释器;
    IPython:在CPython基础之上开发,交互方式上有所增强;
    PyPy:采用动态编译技术,可以显著提高Python代码的执行速度,绝大部分Python代码都可以在PyPy下运行,但是PyPy和CPython有一些是不同的,导致相同的Python代码在两种解释器下执行可能会有不同的结果;
    Jython:是运行在Java平台上的Python解释器,可以直接把Python代码编译成Java字节码执行
    IronPython:IronPython和Jython类似,只不过IronPython是运行在微软.Net平台上的Python解释器,可以直接把Python代码编译成.Net的字节码。
    (总结:Python的解释器很多,但使用最广泛的还是CPython。如果要和Java或.Net平台交互,最好的办法不是用Jython或IronPython,而是通过网络调用来交互,确保各程序之间的独立性。)

    【Python交互模式的进入和退出:】
    1.打开CMD,输入Python,界面出现如下字符串,即进入成功,如果失败,查看环境变量是否配置成功;
    Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 20:20:57) [MSC v.1600 6
    Type "help", "copyright", "credits" or "license" for more information.
    >>>
    2.输入exit(),即可退出交互模式;

    【Python文件运行:】
    进入交互模式,输入python hello.py,即可执行python脚本文件

    【Python编写工具:】
    1.文本编辑器:Sublime Text、Notepad++等;(不能使用电脑自带的记事本)
    2.IDE工具:Eclipse插件、PyCharm等;

    【Python注解、缩进】
    单行注释:#
    多行注释:/**/
    缩进为四个空格

    【Python数据类型】
    整数(精确计算,没有大小限制)
    浮点数(存在计算误差,没有大小限制,但是超出一定范围就直接表示为inf)
    字符串(使用''或者""包裹,转义使用反斜杠,r''不转义,'''...'''换行)
    布尔值(True,False)
    空值(None)

    【Python变量】
    变量的实际值为"="右边对象的内存首地址


    【Python常量】
    通常用大写的字符表示常量

    【Python字符编码】(# -*- coding: utf-8 -*-)
    >>>'中文'.encode('utf-8')
    b'xe4xb8xadxe6x96x87'
    >>>b'xe4xb8xadxe6x96x87'.decode('utf-8')
    '中文'
    # 如果bytes中只有一小部分无效的字节,可以传入errors='ignore'忽略错误的字节:
    >>> b'xe4xb8xadxff'.decode('utf-8', errors='ignore')
    '中'
    # len()函数计算的是str的字符数,如果换成bytes,len()函数就计算字节数:
    >>> len('ABC')
    3
    >>> len('中文')
    2
    >>> len(b'ABC')
    3
    >>> len(b'xe4xb8xadxe6x96x87')
    6
    >>> len('中文'.encode('utf-8'))
    6

    【Python字符串格式化】
    >>> print('%2d-%02d' % (3, 1))
    3-01
    >>> print('%.2f' % 3.1415926)
    3.14
    常见的占位符有:
    占位符 替换内容
    %d 整数
    %f 浮点数
    %s 字符串
    %x 十六进制整数
    format()
    >>> 'Hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.125)
    'Hello, 小明, 成绩提升了 17.1%'

    【Python列表(list)处理】(可变的有序集合)
    申明:list = [1,2,3]
    长度:len(list)
    取值:list[i](从0开始)
    赋值:list[i] = 5
    新增值:
    在最后添加: list.append(4)
    在第i位添加: list.insert(i, 'a')
    删除值:
    在最后删除: list.pop()
    删除第i位: list.pop(i)

    【Python元祖(tuple)处理】(不可变的有序集合)
    申明:tuple = (1,2,3),当只有一个元素的时候元素后面加上逗号
    长度:len(tuple)
    取值:tuple[i](从0开始)

    【Python字段(dict)处理】(可变无序集合)
    申明:dict = {'name': 'test', 'age': 18}
    长度:len(dict)
    取值:dict[name] 或者 dict.get('name', '1') 其中当'name'不存在时返回'1'
    赋值:dict[age] = 5
    检验key是否存在:'address' in dict
    删除:pop('name')
    字典的key是不可变对象,所以list不能做key

    【Python集合(set)】(无序无重复数据的key集合)
    申明:set = set([1, 1, 2, 3]) 结果:{1, 2, 3}
    长度:len(set)
    新增值:set.add(1)
    删除值:set.remove(1)
    交集: {1, 2, 3} & {2, 3, 4}
    并集: {1, 2, 3} | {2, 3, 4}

    【Python条件判断】
    age = input()
    age = int(age)
    if age < 6:
    print('child')
    elif age>=6 and age<18:
    print('your age is', age)
    else:
    print('adult')

    【Python循环】
    break和continue都可用
    第一种:
    for str in list(range(10)):
    print(str)
    第二种:
    n = 0
    while n<10:
    print(n)
    n += 1
    print(n)

    【Python函数】
    def test(name):
    print('hello', name)
    pass功能占位符
    #函数真实的返回值是一个tuple!但是,在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值,所以,Python的函数返回多值其实就是返回一个tuple,但写起来更方便。
    1.位置参数
    def fun(x, y):
    pass
    2.默认参数
    def fun(x, y=5):
    pass
    #一是必选参数在前,默认参数在后,否则Python的解释器会报错
    #使用默认参数有什么好处?最大的好处是能降低调用函数的难度。
    #定义默认参数要牢记一点:默认参数必须指向不变对象!(http://www.cnblogs.com/wuchenggong/p/9505119.html)
    3.可变参数
    def calc(*numbers):
    pass
    #调用calc(1, 2, 3)
    相当于:
    将参数转变成tuple:(1, 2, 3)
    将列表赋给numbers
    4.关键字参数
    def person(name, age, **kw):
    pass
    #调用person(1, 2, city='shanghai',phone=12345678901)
    相当于:
    将参数转变成dict:{'city': 'shanghai', 'phone': 12345678901}
    将字典赋给kw
    5.命名关键字参数
    def person(name, age, *, city, job):
    pass
    #使用"*"分隔固定参数和关键字参数,且只能传指定key的关键字参数
    #当存在可变参数时,无需"*"分隔,例如def person(name, age, *numbers, city, job)
    6.参数组合
    在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
    7.递归函数(看到最后...^-^)
    a.使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。
    b.解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。
    c.尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。
    d.遗憾的是,大多数编程语言没有针对尾递归做优化,Python解释器也没有做优化,所以,即使把上面的fact(n)函数改成尾递归方式,也会导致栈溢出。

    【Python切片】
    语法:list[begin:end:gap]
    范围:大于等于begin,小于end(当begin为空时,从0开始;当end为空时,从-1结束)
    gap:相邻两个元素的倍数
    字符串和tuple也可以切片,且返回的数据类型不变

    【Python迭代】
    list或者tuple或者字符串: for ... in ...
    dict:
    key迭代: for key in dict:
    value迭代: for value in dict.values():
    key-value迭代: for k, v in dict.items():
    ##判断一个对象是否可以迭代:
    导入collections模块的iterable类型:from collections import Iterable
    isinstance('abc', Iterable) #abc是否可以迭代,返回boolean类型
    ##迭代带下角标list:
    for i, value in enumerate(list):

    【Python列表生成式】
    例子:list = [i * j for i in range(1, 11) for j in range(1, 11) if i % 2 == 0 and j <= 5]
    i*j:变量表达式
    for i in range(1, 11): 循环变量, [1,10),存在多个相当于内嵌多个循环
    if i % 2 == 0 and j <= 5: 循环限制条件

    【Python生成器(generator)】
    在Python中,这种一边循环一边计算的机制,称为生成器:generator。
    第一种:
    将列表生成式的"[]"改成"()",即可生成一个generator
    获取generator元素:next(g)
    第二种:
    如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
    如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中.对于函数改成的generator来说,遇到return语句或者执行到函数体最后一行语句,就是结束generator的指令,for循环随之结束。

    【Python迭代器】
    迭代对象(Iterable):
    一类是集合数据类型,如list、tuple、dict、set、str等;
    一类是generator,包括生成器和带yield的generator function。
    这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。
    迭代器(Iterator):
    可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。(类似generator.
    迭代对象和迭代器转换:Iterator = iter(Iterable)
    这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算.

    【Python函数式编程】
    函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。
    函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!
    Python对函数式编程提供部分支持。由于Python允许使用变量,因此,Python不是纯函数式编程语言。

    【Python高阶函数】
    可以接受函数对象为参数的函数,叫做高阶函数
    例如 x = fun()
    其中:
    x为函数的返回值;
    fun为函数名,相当于一个变量,指向函数对象;
    fun()为函数调用;

    【Python高阶函数之map/reduce】
    map函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。
    reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,
    使用reduce方法前,需要先引入from functools import reduce

    【Python高阶函数之filter】
    filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。返回为Iterator,由于filter()使用了惰性计算,所以只有在取filter()结果的时候,才会真正筛选并每次返回下一个筛出的元素。

    【Python高阶函数之sorted】
    不传key:
    例子: sorted([36, 5, -12, 9, -21])
    数字类型按照大小排序;
    字符串类型按照ascll排序;
    传key:
    例子: sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower)
    sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序,例如按绝对值大小排序

    【Python返回函数】
    高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回.
    在一个函数中创建函数,并将这个函数的函数名返回,当程序接受该返回值时并没有进行函数调用,只有当主动进行函数调用才会运行,
    且每次返回的函数都是一个新的函数对象.
    例子:
    def lazy_sum(*args):
    def sum():
    ax = 0
    for n in args:
    ax = ax + n
    return ax
    return sum
    #闭包
    sum称为闭包
    返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
    例子1:
    def count():
    fs = []
    for i in range(1, 4):
    def f():
    return i*i
    fs.append(f)
    return fs

    f1, f2, f3 = count()
    如果一定要引用循环变量怎么办?方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变
    例子2:
    def count():
    def f(j):
    def g():
    return j*j
    return g
    fs = []
    for i in range(1, 4):
    fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f()
    return fs
    综上:例子1和例子2都存储的是函数对象,区别在于例子2绑定了参数

    【Python匿名函数】
    lambda x: x * x
    等价于
    def f(x):
    return x*x
    lambda表示匿名函数
    ":"前面的x表示参数
    ":"后面表示函数体
    函数返回值为表达式的值,本质上是一个函数对象

    【Python装饰器】
    在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。
    本质上,decorator就是一个返回函数的高阶函数。
    例子1:
    import functools
    def log(func):
    @functools.wraps(func)
    def wrapper(*args, **kw):
    print('call %s():' % func.__name__)
    return func(*args, **kw)
    return wrapper
    使用:
    @log()
    def now():
    print('this is now method...')
    @log相当于 now = log(now)
    执行log()函数->返回未执行的wrapper函数对象,并由now变量指向该函数对象
    此时now.__name__等于wrapper(使用@functools.wraps(func):自定义函数的name为now)
    当now执行时now(),则实际上执行的是wrapper的函数体+func(*args, **kw)
    依次实现类似java的aop功能
    带参数
    例子2:
    import functools
    def log(text):
    def decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kw):
    print('%s %s():' % (text, func.__name__))
    return func(*args, **kw)
    return wrapper
    return decorator
    使用:
    @log('execute')
    def now():
    print('this is now method...')
    @log相当于 now = log('execute')(now) 得到一个wrapper对象

    【Python偏函数】
    当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。
    int2 = functools.partial(int, base=2)
    int('12345', base=2)等价于int2('12345')

    【Python模块】
    每一个包目录下面都会有一个__init__.py的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。__init__.py可以是空文件,也可以有Python代码,因为__init__.py本身就是一个模块,而它的模块名就是mycompany。
    mycompany
    ├─ __init__.py
    ├─ abc.py
    └─ xyz.py
    sys.argv:获取传入参数,默认第一个参数为.py文件的名称
    当前模块中Python解释器把一个特殊变量__name__置为__main__,当引入到其他模块时失效
    作用域:
    __xxx__:可被引用,但是有特殊含义
    _xxx:可以被引用,但是不建议引用
    __xxx:不能被引用,(python隐式转换成(对象._类名__xxx))

    【Python第三方模块】
    使用第三方包管理工具pip安装
    pip install Pillow(包名)
    pypi.python.org:该网站提供大量第三方包
    >>>>>>>>且慢!有更好的方法!<<<<<<<<
    https://www.anaconda.com/download/
    Anaconda,这是一个基于Python的数据处理和科学计算平台,它已经内置了许多非常有用的第三方库,我们装上Anaconda,就相当于把数十个第三方模块自动安装好了,非常简单易用。

    【Python面向对象编程】
    a.类和实例
    申明一个类:(object表示该类继承自哪一个类)
    class Student(object):
    pass
    创建对象:student = Student()
    设置属性:student.name
    设置默认属性:
    def __init__(self, name, score):
    self.name = name
    self.score = score
    __init__:相当于构造函数
    self:相当于this
    和普通的函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量self,并且,调用时,不用传递该参数。除此之外,类的方法和普通函数没有什么区别,所以,你仍然可以用默认参数、可变参数、关键字参数和命名关键字参数。
    b.访问限制
    #在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name__、__score__这样的变量名。
    #有些时候,你会看到以一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。
    #双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量.
    c.继承和多态
    相同点:和java的思想一致;
    不同点:鸭子类型
    当一个A类具有某个方法M,另外一个B类即使不去继承A类,但只要也具有方法M,那么isinstance(B, A)同样会返回True
    ##Python多重继承(java不允许多继承)
    MixIn
    class Dog(Mammal, RunnableMixIn, CarnivorousMixIn):
    pass

    【Python获取对象信息】
    1.获取对象类型
    a.常规类型
    引入types模块:import types
    type(fun) == types.FunctionType
    b.isinstance()
    object->Animal->Dog
    isinstance(dog, Dog) >>>>>>>True
    isinstance(dog, Animal) >>>>True
    isinstance(dog, object) >>>>True
    2.获取对象所有属性和方法
    dir(obj)
    3.操作对象属性和方法
    setattr():设置属性
    hasattr():判断属性是否存在
    getattr():获取属性
    obj = object()
    setattr(obj, 'name', 'jl')
    hasattr(obj, 'name')
    getattr(obj, 'name') 或者 getattr(obj, 'age', 17) 当属性不存时返回默认参数

    【Python实例属性和类属性】
    在编写程序的时候,千万不要对实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性,但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性。

    【Python给类和实例绑定成员】
    class Test(object):
    pass
    test = Test()
    1.给实例绑定属性和方法,则只有该实例可以使用;给类绑定属性和方法则所有实例都可以使用
    2.限制实例属性
    为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的
    class Student(object):
    __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称
    3.校验属性
    把一个getter方法变成属性,只需要加上@property就可以了,此时,@property本身又创建了另一个装饰器@score.setter,负责把一个setter方法变成属性赋值
    例子:
    class Student(object):

    @property
    def score(self):
    return self._score

    @score.setter
    def score(self, value):
    if not isinstance(value, int):
    raise ValueError('score must be an integer!')
    if value < 0 or value > 100:
    raise ValueError('score must between 0 ~ 100!')
    self._score = value

    【Python定制类】
    1.__str__()
    类似java的toString()
    2.__repr__()
    功能和__str__()一样,前者是print触发的
    3.__iter__()
    实现for ... in语法需要提供的函数,与__next__()连用才能生效
    4.__getitem__()
    用于实现按照下标获取元素,也可兼容切片(没有对step和负数参数做处理)
    5.__setitem__()
    用于给对象赋值
    6.__delitem__()
    用于删除对象
    7.__getattr__()
    用于调用不存在的属性时,预防报错,且只有当对象获取不存在的属性时,才会调用该方法,当该方法中没有特殊处理的属性,一律返回None
    8.__call__()
    实例调用,实现该方法可以将对象当成函数使用
    使用callable(obj),返回True能被调用,False不能被调用

    【Python枚举类】
    1. 枚举的定义
    class Color(Enum):
    red = 5
    blue = 1
    yellow = 1
    1.1 定义枚举时,成员名称不允许重复
    1.2 默认情况下,不同的成员值允许相同。但是两个相同值的成员,第二个成员的名称被视作第一个成员的别名 
    1.3 如果枚举中存在相同值的成员,在通过值获取枚举成员时,只能获取到第一个成员
    1.4 如果要限制定义枚举时,不能定义相同值的成员。可以使用装饰器@unique【要导入unique模块(from enum import Enum, unique)】
    2. 枚举取值
    2.1 通过成员的名称来获取成员
    2.2 通过成员值来获取成员
    2.3 通过成员,来获取它的名称和值
    3. 迭代器
    3.1 枚举支持迭代器,可以遍历枚举成员
    3.2 如果枚举有值重复的成员,循环遍历枚举时只获取值重复成员的第一个成员
    3.3 如果想把值重复的成员也遍历出来,要用枚举的一个特殊属性__members__
    for color in Color.__members__.items():
    print(color)
    4. 枚举比较
    4.1 枚举成员可进行同一性比较(is)
    4.2 枚举成员可进等值比较(==)
    4.3 枚举成员不能进行大小比较
    (参考:https://www.cnblogs.com/ucos/p/5896861.html)

    【Python元类】
    一.type()
    类的数据类型为"type"
    类的实例的数据类型是"模块.类名"
    通过type()创建一个类:
    Hello = type('Hello', (object,), dict(hello=fn))
    1.参数1:class的名称;
    2.参数2:继承的父类集合,注意Python支持多重继承,如果只有一个父类,别忘了tuple的单元素写法;
    3.参数3:class的方法名称与函数绑定,这里我们把函数fn绑定到方法名hello上。
    二.metaclass
    metaclass,直译为元类,简单的解释就是:
    当我们定义了类以后,就可以根据这个类创建出实例,所以:先定义类,然后创建实例。但是如果我们想创建出类呢?那就必须根据metaclass创建出类,所以:先定义metaclass,然后创建类。连接起来就是:先定义metaclass,就可以创建类,最后创建实例。
    例子:
    # metaclass是类的模板,所以必须从`type`类型派生:
    class ListMetaclass(type):
    def __new__(cls, name, bases, attrs):
    attrs['add'] = lambda self, value: self.append(value)
    return type.__new__(cls, name, bases, attrs)
    class MyList(list, metaclass=ListMetaclass):
    pass
    当我们传入关键字参数metaclass时,魔术就生效了,它指示Python解释器在创建MyList时,要通过ListMetaclass.__new__()来创建,在此,我们可以修改类的定义,比如,加上新的方法,然后,返回修改后的定义。
    __new__()方法接收到的参数依次是:
    1.当前准备创建的类的对象;
    2.类的名字;
    3.类继承的父类集合;
    4.类的方法集合。

  • 相关阅读:
    小涛涛的计算器
    Sort排序浅聊
    程序员PC选购
    冒泡排序
    Django之模板
    Django中model的Meta选项
    Django之路由系统
    Django之视图系统
    踏上Flask的不归路(二)
    踏上Flask的不归路(一)
  • 原文地址:https://www.cnblogs.com/jinloooong/p/9609392.html
Copyright © 2020-2023  润新知