Python学习笔记(二)

2020-07-15 14:39:24 浏览数 (1)

赋值、不可变类型与可变类型

Python中一切皆对象,每一次赋值都是对象引用的传递,而部分类型是不可变引用,所以赋值时实际是创建了新对象,引用新对象。

  • 不可变对象 数字、字符串、元组等的变量在赋值时,都是引用新对象
  • 可变类型 List、Set、Dictonary等的变量在赋值时,都是创建新引用,引用旧对象

正则表达式

通过引入Python模块re使用 re.match(正则表达式字符串,原字符串)返回从字符串开始的匹配,不匹配返回none re.search(正则表达式字符串,原字符串)会遍历字符串子串进行匹配直到找到第一个符合的匹配,不匹配返回none 下面为常用正则表达式

  • ^ 匹配字符串开头,比如^[0-9]代表匹配以0-9中的任一数字开头的字符串
  • 匹配字符串结尾,比如[0-9]代表匹配以0-9中的任一数字结尾的字符串
  • [...] 匹配方括号中任一字符,比如[abc]代表匹配字符a,或者字符b,或者字符c
  • [^...] 不匹配方括号中任一字符,比如[^ abc]代表匹配除了字符a,字符b,字符c的其他任一字符
  • . 匹配除了n以外的任一字符
  • d 匹配数字字符,等于[0-9]
  • D 匹配非数字,等于[^0-9]
  • w 匹配单词字符,即[a-zA-Z0-9_]
  • W 匹配非单词字符,即[^a-zA-Z0-9_]
  • s 匹配空白字符
  • S 匹配非空白字符
    • 匹配前一个字符出现零次或无限次,比如sa*s匹配ss、sas、saas
    • 匹配前一个字符出现一次或者无限次,比如sa*s匹配sas、saas
  • ? 匹配前一个字符出现1次或者0次,比如sa?s匹配ss、sas
  • {n} 匹配前一个字符出现n次,比如a{2}匹配aa
  • {n,} 匹配一个字符出现至少n次,比如a{2}匹配aa、aaa、aaaa
  • {n,m} 匹配一个字符至少出现n次,至多出现m次
  • [u4E00-u9FA5] 匹配一个汉字
  • (...) 分组,圆括号在匹配过程只是起分组作用(使得括号内的正则表达式可以当成一个单位原子的正则表达式),在整个表达式匹配成功时,会使用元组来分隔返回每个分组(圆括号)内表达式各自的匹配字符串
  • | 或者匹配,匹配被|分隔的多个正则表达式之一的结果,比如a|b|c等于匹配正则表达式a或者正则表达式b或者正则表达式c,还可以结合分组使用,比如(a|d)s(c|b)代表匹配asc、dsc、asb、dsb

super

super‘返回从传入第二个参数(对象)的MRO类列表从传入的类往右开始寻找到第一个匹配的类,并把传入对象转化为该父类对象返回(可以调用父类同名方法),如果在父类中调用super(比较拗口,就是如果super的第二个参数是一个子类对象),此时如果当前类(super第二个参数的类型,也就是子类的父类)的父类也是该子类对象的MRO父类列表中,在自己右侧的某一父类的父类,则super会定位到该MRO父类执行 在Python3中,super不需要传入参数,默认第一个传入当前类的MRO类列表的第一个类(最左侧),而第二个参数传入self,比如

代码语言:javascript复制
class A(object):
    def f(self):
        print('An')
class B(A):
    def f(self):
        print('Bn')
        super(B,self).f()   
class C(A):
    def f(self):
        print('Cn')
        super(C,self).f()
class E(A):
    def f(self):
        print('En')
        super(E,self).f()
class D(B,C,E):
    def f(self):
        print('Dn')
        super(D,self).f()

d = D()
d.f()

上述代码执行顺序为: D B C E A 总的来说,就是调用super是在转化当前对象为父类对象,因为两个父类具备公共祖先,所以在某个父类转化super时,发现在self对象的MRO列表,比自己后的同级父类有个也是这个祖先的子类(里氏替换原则可以作为祖先类后代看待),所以优先转化为该同级父类对象,而因为是固定的MRO顺序(从左往右),所以不会无限重复。对于同一个对象,不断调用super就是先横向(左到右的具备公共祖先的父类),后纵向(到公共祖先类)

经典类与新式类

如果一个类是object的子类,则他是新式类,否则为经典类,新式类在匹配方法时,使用广度优先原则(最接近当前类的父类方法),而经典类使用深度优先原则(离当前类最遥远的父类方法),比如

代码语言:javascript复制
#新式类
class A(object):
    def f(self):
        print 'A'

class B(A):
    pass

class C(A):
    def f(self):
        print 'C'

class D(B,C):
    pass

d = D()
d.f()    #C

上述新式类最终匹配到的方法是类C中的方法

代码语言:javascript复制
#经典类
class A:
    def f(self):
        print 'A'

class B(A):
    pass

class C(A):
    def f(self):
        print 'C'

class D(B,C):
    pass

d = D()
d.f()    #A

而上述经典类最终匹配到的是最深的类A中的方法

0 人点赞