Python学习笔记(二)

Python学习笔记(二)

    • 赋值、不可变类型与可变类型
    • 正则表达式
    • super
    • 经典类与新式类

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

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,比如

class A(object):
	def f(self):
		print('A\n')
class B(A):
	def f(self):
		print('B\n')
		super(B,self).f()	
class C(A):
	def f(self):
		print('C\n')
		super(C,self).f()
class E(A):
	def f(self):
		print('E\n')
		super(E,self).f()
class D(B,C,E):
	def f(self):
		print('D\n')
		super(D,self).f()

d = D()
d.f()

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

经典类与新式类

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

#新式类
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中的方法

#经典类
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中的方法

更多文章,请搜索公众号歪歪梯Club
更多资料,请搜索公众号歪歪梯Club

你可能感兴趣的:(Python)