32.内置双下方法
内置的方法有很多,不一定全部都在object中,比如len(),数字无法计算长度,没有len()方法
__str__
打印一个对象的时候,就是调用对象.__str__ 用于对对象进行打印说明时
直接打印,%s,str() 这些实际调用的都是__str__,__str__的返回值必定是一个字符串
class A: def __str__(self): #重写__str__方法 return "'A's object" a=A() print(a) #调用a.__str__
__repr__
%r 和repr ,实际上都是调用__repr__,__repr__的返回值必定是一个字符串
_repr__是__str__的备胎,在类中找不到__str__,就会再去寻找使用__repr__,找不到__repr__再去寻找父类的方法
class A: def __init__(self,name,money): self.name=name self.money=money def __repr__(self): return str(self.__dict__) a=A('大黄',250) print(repr(a)) print(a) #这里本应该返回一个对象地址,因为找不到类中的__str__方法,实际上,__repr__是__str__的备胎,在类中找不到__str__,就会再去寻找使用__repr__ print('%r'%a)
__del__
析构函数:在删除一个对象之前,进行一些收尾工作,如关闭文件
执行函数del时,会先调用执行__del__,再删除变量
class A: def __del__(self): print('执行我了') a=A() del a #这里先执行定义的__del__方法里的程序,再将对象a删除 print(a)
执行结果:
执行我了
在程序执行完后,如果没有将对象删除,垃圾回收机制会自动调用__del__方法,删除程序中的变量和对象
验证代码如下:
class A: def __del__(self): print('执行我了') a=A() print(a)#程序没将对象a删除,因此代码结束后会调用__del__()来删除对象a
执行结果:
<__main__.A object at 0x000002245812B5F8>
执行我了
__call__
一个对象加上()相当于执行了__call__,如果类中没有定义__call__,就会报错
class A: def __call__(self): print('执行我了') a=A() a() #执行__call__方法
执行结果:
执行我了
该函数可以用来打印对象的属性或给对象接收参数,代码如下:
class A: def __init__(self,name,money): self.name=name self.money=money def __call__(self,*args): print('执行我了') print(self.name) print(self.money) print(args[1]) a=A('sdd',23) a(1,2,3)
可以通过定义__call__来定义对象名+()时的特定功能
item系列
__getitem__
想要以字典形式获取属性的值时,会自动调用__getitem__,即对象名['属性名']
如果类中没有定义__getitem__,只能以print(a.name)形式获取
class A:
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def __getitem__(self, item):
print('hello')
return self.__dict__[item]
a=A('ass',12,'man')
print(a['name'])
#获取属性name的值,调用__getitem__,如果类中没有定义__getitem__,只能以print(a.name)形式获取
执行结果:
hello
ass
__setitem__
以对象名['属性']=新值的形式来修改属性值时会调用该方法
如果没有该方法,就只能以对象名.属性名的形式修改
class A: def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def __setitem__(self, item,value):
print("修改属性值") self.__dict__[item] = value a=A('ass',12,'man') a['name']='大黄' #如果没有__setitem__,就只能以a.name='大黄'的形式修改 print(a.__dict__)
执行结果:
修改属性值
{'name': '大黄', 'age': 12, 'sex': 'man'}
__delitem__
以del 对象名['属性']的形式删除属性
如果没有__delitem__,只能以del 对象名.属性名来删除属性
class A: def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def __delitem__(self, key):
print('删除属性') del self.__dict__[key] a=A('ass',12,'man') del a['name'] #如果没有__delitem__,只能以del a.name来删除属性 print(a.__dict__)
执行结果:
删除属性
{'age': 12, 'sex': 'man'}
构造方法:
创建一个对象需要的方法
__new__(面试必考) __init__
class A: def __init__(self): print('这里执行__init__') def __new__(cls, *args, **kwargs): print('这里执行__new__') return object.__new__(A,*args,**kwargs) #new是无法实例化一个对象的,自己有object才能实例化一个对象 a=A()
执行结果:
这里执行__new__
这里执行__init__
设计模式:单例模式
一个类始终只有一个实类,单例模式的编码离不开__new__
当你第一次实例化这个类时,就创建一个实例化的对象;之后再来实例化的时候,就用之前创建的对象(想使用新的对象时,就将该对象的所有属性全部重新赋值属性,这样从头到尾就是在操作一个属性)
实现方法:
class A: __instance=False def __init__(self,name,age): self.name=name self.age=age def __new__(cls, *args, **kwargs): if cls.__instance: #非第一次实例化对象时,满足此条件,将上层实例化的对象直接返回 return cls.__instance cls.__instance=object.__new__(A) #第一次实例化对象时,执行此代码 ,将实例化的对象赋值给cls.__instance return cls.__instance #将cls.__instance返回 a=A('大黄',23) b=A('小黄',21) print(a) print(b) #返回的是两个对象的地址,地址完全相同,是同一个对象 print(a.__dict__) #返回的对象b的实现,表示对象a中的属性完全重新赋值 print(b.__dict__)
执行结果:
<__main__.A object at 0x000001A54854DCF8>
<__main__.A object at 0x000001A54854DCF8>
{'name': '小黄', 'age': 21}
{'name': '小黄', 'age': 21}
__eq__
执行==是就是在调用__eq__
__eq__默认比较地址,两个对象的地址不同,默认返回false
class A: def __init__(self,name): self.name=name ob1=A('a') ob2=A('a') print(ob1==ob2) #__eq__默认比较地址,两个对象的地址不同,默认返回false
执行结果:False
对__eq__进行修改,可以以设置根据什么来比较两者是否相同
class A: def __init__(self,name): self.name=name def __eq__(self, other): if self.name==other.name: #定义__eq__方法,两者的name相同,就返回true return True else: return False ob1=A('a') ob2=A('a') print(ob1==ob2)
执行结果:True
__hash__
执行hash()函数时,实际上就是在调用__hash__
只要是可hash的数,都在内部实现了__hash__
class A: def __init__(self,name,sex): self.name=name self.sex=sex def __hash__(self): return hash(self.name+self.sex) a=A('a','man') b=A('b','man') print(hash(a)) #a在内部实现了__hash__,a也变成了可哈希数 print(hash(b))
执行结果:
1211493403233181463
-3611351746756962348

浙公网安备 33010602011771号