new( )
1.调用特殊方法__new__()创建实例对象
2.调用特殊方法__init__()对创建的实例对象进行初始化
class Parent(object):
@classmethod
def __new__(cls, *args, **kwargs):#cls接收的是子类Child
print("父类的__new__()被调用,其形参cls对应实参的id:",id(cls))
obj = super().__new__(cls)
print("创建的实例对象的id:",id(obj))
return obj
class Child(Parent):
def __init__(self, name):
print("子类的__new__()被调用,其形self对应实参的id:",id(self))
self.name = name
child = Child("Mike")
>
>
父类的__new__()被调用,其形参cls对应实参的id: 2505126419896
创建的实例对象的id: 2505132259200
子类的__new__()被调用,其形self对应实参的id: 2505132259200
getitem(),setitem(),delitem()
想像字典或列表一样用中括号来操作数据,必须实现:
1.getitem(self,key)当执行操作obj[key]时,会自动调用该特殊方法
2.setitem(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"] = 18
md["two"] = 32
print(md.data)
>
>
{'one': 18, 'two': 32}
call(),callable()
call():如果在类对象中实现了特殊方法__call__()那么久可以像调用函数一样直接调用这个类对象的实例对象,从而会自动调用特殊方法__call__()
callable():用于判断对象是否可调用,除了函数对象可以调用之外,对于实现了特殊方法__call__()的类对象,其实例对象也是可调用的
class MyClass(object):
def __call__(self, *args, **kwargs):
print(args, kwargs)
mc = MyClass()
mc()
mc(1, 2,5, x = 3, y = 4,d = 6)
>
>
() {}
(1, 2, 5) {'x': 3, 'y': 4, 'd': 6}
callable(print)#内置函数是可调用的
>
>
True
def my_fun():#自定义函数也是可调用的
pass
print(callable(my_fun))
>
>
True
print(callable(MyClass()))#实现了__call__的类对象的实例对象也是可以调用的
>
>
True
doc ,dict
doc:调用内置函数dir得到的类对象的所有属性中,有一个特殊的属性叫__doc__,用于表示类对象的文档字符串。
1.类对象文档字符串:位于类对象的第一行的字符串被称为类对象的文档字符串,通常用三个引号表示,类对象的文档字符串是对类对象的功能的简要概述
2.通过类对象的特殊属性__doc__可以访问类对象的文档字符串
对于指定的类对象或实例对象,可以访问特殊属性__dict__获得该类对象或实例对象所绑定的所有属性和方法的字典
slots
在对应的类对象定义__slots__并给__slots__赋值一个所有元素都为字符串的列表或元组,对实例对象动态绑定的属性和方法的名称就只能来自于__slots__中的元素
class MyClass(object):
__slots__ = ("attr1","do_sth1")
mc = MyClass()
mc.attr1 = 18
print(mc.attr1)
>
>
18
def do_sth1(self):
print("do_sth1被调用了")
from types import MethodType
mc.do_sth1 = MethodType(do_sth1, mc)
mc.do_sth1()
>
>
do_sth1被调用了
默认情况下,访问实例对象的属性是通过访问该实例对象的特殊属性__dict__来实现的,例如:访问obj.x其实是访问obj.dict[‘x’]
在类对象中定义了__slots__()后,其实例对象就不会再创建特殊属性__dict__(),slots()可以提高属性的访问速度
print(MyClass().__dict__)
>
>
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-21-11a41545445d> in <module>
----> 1 print(MyClass().__dict__)
AttributeError: 'MyClass' object has no attribute '__dict__'
slots__只对其所在的类对象的实例对象起作用,对其所在类对象的子类的实例对象不起作用,如父有__slots,子没有,所以他子可以任意调用
len()
如果不用def len(self):那么print(len(MyClass()))就不能用
生成器和迭代器
[i*i for i in range(8)]#列表推导式
>
>
[0, 1, 4, 9, 16, 25, 36, 49]
(i*i for i in range(8))#生成器表达式
>
>
<generator object <genexpr> at 0x00000247458C4840>
查看生成器对应的元素:
1.多次调用next(),每次调用都返回生成器的下一个元素,直到抛出错误
2.使用for循环对生成器进行迭代,这样就不会报错了
a = (i*i for i in range(8))
for j in a:
print(j)
>
>
0
1
4
9
16
25
36
49