旧式类和新式类
python2.2之后全部使用新式类,全局设置新式类属性的方法如下(python3中无需显示写出)。
__metaclass__ = type
魔法方法
特殊命名 __name__
组成的集合所包含的方法称为magic method。如,
__init__
# 位置参数版
class ClassA:
def __init__(self):
self.some_var = 42
# 关键字参数版
class ClassB:
def __init__(self, value = 42):
self.some_var = value
python的
self
变量需要显式的写出来,而c++的this指针则是隐式的。
构造方法
类似于init()的初始化方法。和一般方法不同,当一个对象被创建后,会立即调用构造方法。在python中,使用魔法方法__init__
创建一个构造方法。
构造方法的重写
一般方法
可以通过继承后进行重写。而构造方法
不行。
调用未绑定(unbound)的构造方法
# 先调用超类的__init__再写自己独有的__init__部分
class ClassB(ClassA):
def __init__(self):
ClassA.__init__(self) # 该Method的self会自动"绑定bound"
self.some_var = 'some value'
使用super()函数
class ClassB(ClassA):
def __init__(self):
super(ClassB, self).__init__() # super()犹如直接调用超类
self.some_var = 'some value'
Q:如果超类有2个怎么办?
成员访问
成员访问:可以修改基础的数据结构类。
基本的序列(sequence)和映射的规则(protocol)
序列
和映射
是对象
的集合
如果对象不变可使用下述前2个方法即可。如果可变则可使用下述4个方法。
__len__(self): # 集合中所含项目的数量;
seq:是element个数
映射:是k-v对的个数
__getitem__(self, key): # 返回key对应的value
__setitem__(self, key, value): # 设置k-v值,只能对可修改的对象使用
__delitem__(self, key): # 删除k-v值
举个栗子:
a[0] # __getitem__
a[0] = 1 # __setitem__
del seq[4] # __delitem__
属性property
property函数
属性property:通过访问器定义的attribute。
property(fget=None, fset=None, fdel=None, doc=None)
静态方法和类成员方法
- staticmethod(没有self参数)
- classmethod(类似self的cls参数)
例如:
class MyClass:
def smethod(): # 没有self参数
print("this is static method")
smethod = staticmethod(smethod)
def cmethod(cls): # cls参数
print("this is class method")
cmethod = classmethod(cmethod)
装饰器 decorator
- 使用@操作符
- 手动包装和替换方法或函数的技术
- 多个装饰器在应用时的顺序与指定时的顺序相反
装饰器本身可以另起文章单独讨论,这里只是简单的提及。
__getattr__和__setattr__
拦截(intercept)对象的所有特性访问,使旧式类实现property()
注意:
__getattribute__拦截(intercept)所有特性的访问(在新式类中,包括__dict__)。而访问__getattribute__和self相关特性时,使用超类super() 的__getattribute__是唯一安全途径
迭代器 iterator
迭代:重复做一些事很多次
__iter__
方法返回一个迭代器(iterator)- 而迭代器是具有
__next__
方法(此方法无需参数)的对象
一个实现了__iter__
方法的对象是可迭代的,而一个实现了__next__
方法的对象是迭代器。
生成器 generator
调用生成器函数()
不会执行这个函数,而是返回一个iterable
对象。在for循环执行时,每次循环都会执行生成器函数()
内部的代码,直到执行到yield
时,生成器函数()
就返回一个迭代值,下次迭代时,代码从yield
的下一条语句继续执行。
相当于说是:生成器 = 生成器函数 + 迭代器
参考
迭代器和生成器的一些细节可以参考另一篇博文:
python的迭代器iterator和生成器generator(关键字yield)的简单理解
循环生成器
列表推导式[] [list comprehension] 轻量级循环
生成器推导式() (generator comprehension)
e.g.
列表推导式[]
l = [(x, y) for x in range(2) for y in range(2)]
生成器推导式()
g = ((i+2) ** 2 for i in range(2, 7))
print(g.__next__())
列表推导式[]会立即实例化一个列表,而生成器推导式()只是单一次结果
生成器方法
1. __next__
2. send()
send()
- 外部作用域访问send()方法,就像访问iterator的__next__()方法,但send()需要参数
- send()只有在generator挂起后才有意义(即yield在第一次被执行后)。或者对刚启动的generator用None参数调用send()方法
如:
foo.__next__()
foo.send(param)
其他函数
isinstance(obj, classinfo) # is obj belongs to classinfo