- 包含以下内容:
__new __()
__getitem() __, __setitem __(), __delitem __()
__call __() 与callable()
__doc __ 与 __dict __
__slots __
__len() __
生成器与迭代器
__new __()
当使用"类名([实参])"创建实例对象时,Python解释器主要处理过程包括两大步:
1、调用特殊方法__new__()创建实例对象,如果没有实现则去其父类中依次查找直到object
2、调用特殊方法__init__()对创建的实例对象进行初始化
class Parent(object):
def __new__(cls,*args,**kwargs):
pass
class Child(Parent):
def __init__(self,name):
pass
id(Parent)
2198166265416v
id(Child)
2198166266360
class Parent(object):
def __new__(cls,*args,**kwargs):
print("父类的__new__()被调用,其形参cls对应实参的id",id(cls))
obj = super().__new__(cls)
print("创建的实例对象的id:",id(obj))
return obj
class Child(Parent):
def __init__(self,name):
print("子类的__init__()被调用,其形参self对应实参的id",id(self))
self.name = name
child = Child("Mike")
父类的__new__()被调用,其形参cls对应实参的id 2198166271080
创建的实例对象的id: 2198191076352
子类的__init__()被调用,其形参self对应实参的id 2198191076352
getitem() setitem() delitem()
如果想让自定义类对象的实例对象可以像列表和字典一样使用中括号来操作数据,必须在自定义类对象中实现以下特殊方法:
1.getitem(self,key),当执行object[key]时,会自动调用该特殊方法
2.steitem(self,key,value),当执行obj[key] = value
3.delitem(self,key),当执行 del obj(key)
class MyDict(object):
def __init__(self):
self.data = {}
def __getitem__(self,key):
return self.data[key]
def __setitem__(self,key,value):
self.data[key] = value
def __delitem__(self,key):
del self.data[key]
md = MyDict()
md['one'] = 16
md['two'] = 32
print(md.data)
{'one': 16, 'two': 32}
del md['two']
print(md.data)
{'one': 16}
__call __()
如果类对象中实现了特殊方法__call__(),name就可以想调用函数一样直接调用这个类对象的实例对象,从而会自动调用特殊方法__call__()
class MyClass(object):
def __call__(self,*args,**kwargs):
print(args,kwargs)
mc = MyClass()
mc()
() {}
mc(1,2,x=3,y=4)
(1, 2) {'x': 3, 'y': 4}
callable,内置函数,用于判断指定对象是否可调用
callable(print)
True
def my_fun():
pass
print(callable(my_fun))
True
print(callable(MyClass()))
True
'''
class MyClass(object):
def __init__(): (1)
...
def __call__(): (2)
...
mc = MyClass() 调用的1函数
mc() 调用的2函数
'''
doc,特殊属性,用于表示类对象的文档字符串
class MyClass(object):
'''这是类对象的文档字符串
1
2
3
'''
pass
print(MyClass.__doc__)
这是类对象的文档字符串
1
2
3
print(help(MyClass))
Help on class MyClass in module __main__:
class MyClass(builtins.object)
| 这是类对象的文档字符串
| 1
| 2
| 3
|
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
None
dict,特殊属性
获得该对象或实例对象所绑定的所有属性和方法的字典,其中,字典中的键为属性名或方法名。
slots,特殊属性
如果想要对实例对象动态绑定的属性和方法的名称进行限制,可以在其对应的类对象中定义特殊属性__slots__,并给__slots__复制一个所有元素都为字符串的列表或元组,这样对实例对象动态绑定的属性和方法的名称就只能来自于__slots__的元素
class MyClass(object):
__slots__ = ("attr1","do_sth1")
mc = MyClass()
mc.attr1 = 18
print(mc.attr1)
18
特殊方法之 __len() __
class MyClass(object):
def __len__(self):
return 18
print(len(MyClass()))
18
生成器
查看生成器对应的所有原属,有两种方式:
1、多次调用内置函数next(),每次调用都返回生成器的下一个元素,知道抛出异常StopIteration时表示没有更多元素了
2、使用for-in语句对生成器进行迭代,这样就不需要关心异常StopIteration了
生成器函数 yield
生成器海曙与普通函数的区别在于:当调用内置函数next()或使用for-in语句进行迭代式,执行为yield语句就会将升车藏起函数挂起,下次会从挂起的地方继续执行
def fib(n):
i = 0
a, b = 1, 1
while i < n:
print(a,end = ',')
a, b = b, a + b
i += 1
fib(6)
1,1,2,3,5,8
def fib(n):
i = 0
a, b = 1, 1
while i < n:
yield a
a, b = b, a + b
i += 1
fib(6)
<generator object fib at 0x0000022F6DA9EA20>
gf = fib(6)
for item in gf:
print (item)
1
1
2
3
5
8
迭代器
可以调用内置函数isinstance()判断一个对象是否是可迭代对象。标准库模块collections中的类Iterable用于表示可迭代对象
from collections import Iterable
print(isinstance([1,2,3],Iterable))
True
print(isinstance('abc',Iterable))
True
print(isinstance((i * i for i in range(1,7)),Iterable))
True
#如果一个可迭代对象可以作为内置函数next()的实参从而支持惰性推算,那么该对象被称为迭代器(Iterator)对象
L = [1,2,3]
S = 'abc'
from collections import Iterator
print(isinstance(L,Iterator))
False
print(isinstance(S,Iterator))
False
print(isinstance((i * i for i in range(1,7)),Iterator))
True
#可调用内置函数iter()把不支持惰性推算的可迭代对象转换为迭代器对象
iter_L = iter(L)
iter_S = iter(S)
print(isinstance(iter_L,Iterator))
True
print(isinstance(iter_S,Iterator))
True