美文网首页
廖雪峰的教程学习笔记

廖雪峰的教程学习笔记

作者: 风若水兮 | 来源:发表于2017-09-05 16:02 被阅读0次

    变量

    转义:加很多\,为了简化,Python还允许用r''表示''内部的字符串默认不转义

    换行:允许用'''...'''的格式表示多行内容

    空值:用None表示

    字符串和编码:

    Unicode把所有语言都统一到一套编码里,本着节约的精神,又出现了把Unicode编码转化为“可变长编码”的UTF-8编码。UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间:

    len()函数:

    要计算str包含多少个字符,可以用len()函数:

    如果换成bytes,len()函数就计算字节数

    当Python解释器读取源代码时,为了让它按UTF-8编码读取,我们通常在文件开头写上这两行:

    #!/usr/bin/env python3

    # -*- coding: utf-8 -*-

    常见的占位符有:

    %d

    整数

    %f

    浮点数

    %s

    字符串

    %x

    十六进制整数

    list和tuple:

    l列表:list。list是一种有序的集合,可以随时添加和删除其中的元素。list里面的元素的数据类型也可以不同

    得索引是从0开始的.如果要取最后一个元素,除了计算索引位置外,还可以用-1做索引;

    插入:可以往list中追加元素到末尾也可以把元素插入到指定的位置,比如索引号为1的位置:

    >>>classmates.insert(1,'Jack')

    删除:list末尾的元素,用pop()方法,删除指定位置的元素,用pop(i)方法,其中i是索引位置;

    替换:直接赋值给对应的索引位

    ltuple和list非常类似,但是tuple一旦初始化就不能修改。只有1个元素的tuple定义时必须加一个逗号,,来消除歧义

    if的完整语句:

    if<条件判断1>:

    <执行1>

    elif<条件判断2>:

    <执行2>

    elif<条件判断3>:

    <执行3>

    else:

    <执行4>

    dict:dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储

    set:也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。

    切片:L[0:3]表示,从索引0开始取,直到索引3为止,但不包括索引3。即索引0,1,2,正好是3个元素。如果第一个索引是0,还可以省略,也支持倒数切片L[-2:]

    生成器:一边循环一边计算的机制

    第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator

    generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误

    repe::器:可以直接作用于for循环的对象统称为可迭代对象:Iterable

    可以使用isinstance()判断一个对象是否是Iterable对象

    map/reduce:map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。

    reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:

    reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

    filter:filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素

    s.strip(rm)删除s字符串中开头、结尾处,位于rm删除序列的字符,当rm为空时,默认删除空白符(包括'\n', '\r',  '\t',  ' ')

    sorted:排序算法

    可以接收一个key函数来实现自定义的排序

    返回函数:我们在函数lazy_sum中又定义了函数sum,并且,内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力。

    返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。

    匿名函数:lambda

    只能有一个表达式,不用写return,返回值就是该表达式的结果

    装饰器:

    假设我们要增强now()函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改now()函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。

    decorator就是一个:使用函数作参数并且返回函数的函数

    因为返回的那个wrapper()函数名字就是'wrapper',所以,需要把原始函数的__name__等属性复制到wrapper()函数中,否则,有些依赖函数签名的代码执行就会出错。

    不需要编写wrapper.__name__

    = func.__name__这样的代码,Python内置的functools.wraps就是干这个事的,所以,一个完整的decorator的写法如下:

    importfunctools

    deflog(func):

    @functools.wraps(func)

    defwrapper(*args, **kw):

    print('call %s():'% func.__name__)

    returnfunc(*args, **kw)

    returnwrapper

    只需记住在定义wrapper()的前面加上@functools.wraps(func)即可。并且记得import functools

    偏函数:

    import functools

    简单总结functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。

    当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。

    模块:使用模块还可以避免函数名和变量名冲突。相同名字的函数和变量完全可以分别存在不同的模块中。

    不要与内置函数名字冲突

    Built-in Functions

    abs()dict()help()min()setattr()all()dir()hex()next()slice()any()divmod()id()object()sorted()ascii()enumerate()input()oct()staticmethod()bin()eval()int()open()str()bool()exec()isinstance()ord()sum()bytearray()filter()issubclass()pow()super()bytes()float()iter()print()tuple()callable()format()len()property()type()chr()frozenset()list()range()vars()classmethod()getattr()locals()repr()zip()compile()globals()map()reversed()__import__()complex()hasattr()max()round()delattr()hash()memoryview()set()

    为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package)。

    引入了包以后,只要顶层的包名不与别人冲突,那所有模块都不会与别人冲突。

    每一个包目录下面都会有一个__init__.py的文件,这个文件是必须存在的。

    模块的使用:(一下是标准文件模板)#!/usr/bin/env python3

    # -*- coding: utf-8 -*-

    ' a test module '#模块的文档注释

    __author__ ='Michael Liao'

    作用域(函数和变量名):为了封装和抽象

    lPublic:可以被直接引用

    __xxx__特殊变量,可被直接引用,也有特殊用途。自己的变量一般不用这种变量名。

    lPrivate:不应被直接引用

    _xxx和__xxx

    外部不需要引用的函数全部定义成private,只有外部需要引用的才定义为public。

    安装第三方模块:

    在Python中,安装第三方模块,是通过包管理工具pip完成的。

    打开cmd,输入:pip install xxx

    加载模块:import xxx(!!!)

    如果提示:name”xxx” not defined或者not found很有可能是没有import

    默认情况下,Python解释器会搜索当前目录、所有已安装的内置模块和第三方模块,搜索路径存放在sys模块的path变量中:

    面向对象编程:

    面向对象编程——Object

    Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。

    init称为构造函数或者初始程序,初始化类或对象的实例,在这个_init_下,新创立的对象就是self.

    class Dog: definit(self, legs,colour): self.legs = legs self.colour = colour

    fido = Dog(4, "brown") spot =Dog(3, "mostly yellow"

    对一只狗来说:_init_就是第一次写了一些信息的出生证明,几斤重,在哪里出生等等

    变量self就是它以后会成为的那条狗。而self.color或者self.legs或self.xx就是它今后的改变会成为怎么样一只狗,黄色3条腿或其他

    然后有个例子关于Class中的变量和_init_函数中的变量的差别class MyClass(object): i = 123 def _init_(self): self.i =

    345 print(MyClass().i)345 print(MyClass.i)123

    类和实例:

    classStudent(object):

    pass

    class后面紧接着是类名,即Student,类名通常是大写开头的单词,紧接着是(object),表示该类是从哪个类继承下来的,继承的概念我们后面再讲,通常,如果没有合适的继承类,就使用object类,这是所有类最终都会继承的类。

    由于类可以起到模板的作用,因此,可以在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去。通过定义一个特殊的__init__方法,在创建实例的时候,就把name,score等属性绑上去:

    注意:特殊方法“init”前后有两个下划线!!!

    classStudent(object):

    def__init__(self, name, score):

    self.name = name

    self.score = score

    数据封装:

    直接在Student类的内部定义访问数据的函数,这样,就把“数据”给封装起来了。这些封装数据的函数是和Student类本身是关联起来的,我们称之为类的方法:

    方法就是与实例绑定的函数,和普通函数不同,方法可以直接访问实例的数据;

    和静态语言不同,Python允许对实例变量绑定任何数据,也就是说,对于两个实例变量,虽然它们都是同一个类的不同实例,但拥有的变量名称都可能不同:

    也就是说,对A在类外定义了新的age属性,但B是没有这个属性的!

    访问限制:

    如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),

    l只有内部可以访问,外部不能访问:直接用bart.__name就无法得到结果

    l这样就确保了外部代码不能随意修改对象内部的状态

    l外部代码要获取变量:在类中定义:get_name函数

    l又要允许外部代码修改score,给Student类增加set_score方法:

    在方法中,可以对参数做检查,避免传入无效的参数

    l需要注意的是,在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name__、__score__这样的变量名。

    l看到以一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。

    l不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name

    l虽然可以通过_Student__name来访问__name变量,但不同版本的Python解释器可能会把__name改成不同的变量名

    l注意下面的这种错误写法:

    l>>>bart = Student('Bart Simpson',98)

    l>>>bart.get_name()

    l'Bart Simpson'

    l>>>bart.__name ='New Name'#设置__name变量!

    l>>>bart.__name

    l'New Name'

    继承和多态:

    在继承关系中,如果一个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类。但是,反过来就不行。

    定义父类:classAnimal(object):

    Pass

    定义子类:class Dog(Animal):

    Pass

    获取对象信息:

    1.先判断对象类型--type()

    type(对象)函数返回的是什么类型呢?它返回对应的Class类型

    2.判断class的类型—isinstance()

    Isinstance(对象,类名)。可反映class的继承关系

    3.能用type()判断的基本类型也可以用isinstance()判断

    4.还可以判断一个变量是否是某些类型中的一种

    isinstance([1,2,3], (list, tuple))

    就是判断是不是属于list或者tuple中的一种

    5.要获得一个对象的所有属性和方法—dir()

    返回的是一个包含字符串的list

    6.仅把属性和方法列出来是不够的,配合getattr()、setattr()以及hasattr(),我们可以直接操作一个对象的状态

    hasattr(obj,'x')#有属性'x'吗?

    setattr(obj,'y',19)#设置一个属性'y'

    getattr(obj,'y')#获取属性'y'

    getattr(obj,'z',404)#获取属性'z',如果不存在,返回默认值404

    实例属性和类属性:

    lStudent类本身需要绑定一个属性呢?可以直接在class中定义属性,这种属性是类属性,归Student类所有

    l实例绑定属性的方法是通过实例变量,或者通过self变量

    相关文章

      网友评论

          本文标题:廖雪峰的教程学习笔记

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