Python的Class机制内置了很多特殊的方法来帮助使用者高度定制自己的类,这些内置方法都是以双下划线开头和结尾的,会在满足某种条件时自动触发。
1.__str__
str_方法会在对象被打印时自动触发,print功能打印的就是它的返回值,我们通常基于方法来定制对象的打印信息,该方法必须返回字符串类型
>>> class People:
... def __init__(self,name,age):
... self.name=name
... self.age=age
... def __str__(self):
... return '<Name:%s Age:%s>' %(self.name,self.age) #返回类型必须是字符串
...
>>> p=People('lili',18)
>>> print(p) #触发p.__str__(),拿到返回值后进行打印
<Name:lili Age:18>
2.__del__(析构函数)
del_会在对象被删除时自动触发。由于Python自带的垃圾回收机制会自动清理Python程序的资源,所以当一个对象只占用应用程序级资源时,完全没必要为对象定制_del_方法,但在产生一个对象的同时涉及到申请系统资源(比如系统打开的文件、网络连接等)的情况下,关于系统资源的回收,Python的垃圾回收机制便派不上用场了,需要我们为对象定制该方法,用来在对象被删除时自动触发回收系统资源的操作
class MysqL:
def __init__(self,ip,port):
self.conn=connect(ip,port) # 伪代码,发起网络连接,需要占用系统资源
def __del__(self):
self.conn.close() # 关闭网络连接,回收系统资源
obj=MysqL('127.0.0.1',3306) # 在对象obj被删除时,自动触发obj.__del__()
3.__init__
init()方法 当使用类名()创建对象时,Python解释器会自动执行以下操作:
A.为对象在内存中分配空间 创建对象
B.调用初始化方法为对象的属性设置初始值-初始化方法(init)
C.这个初始化方法是对象的内置方法,是专门用来定义一个类具有哪些属性的方法
4.__getattr__、__setattr__、__delattr__
之前介绍反射的时候说过,但是,这里有些许不同,内置方法里面没有hasattr
当使用obj.x = y
的时候触发对象的setattr
方法,当del obj.x
的时候触发对象的delattr
方法。
当尝试访问对象的一个不存在的属性时 obj.noexist
会触发getattr
方法,getattr
方法是属性查找中优先级最低的。
可以重写这3个方法来控制对象属性的访问、设置和删除。
**特别注意:如果定义了getattr,而没有任何代码(即只有pass),则所有不存在的属性值都是None而不会报错,可以使用super().__getattr__()方法来处理**
class Student:
def __getattr__(self, item):
print('访问一个不存在的属性时候触发')
return '不存在'
def __setattr__(self, key, value):
print('设置一个属性值的时候触发')
# self.key = value # 这样会无限循环
self.__dict__[key] = value
def __delattr__(self, item):
print('删除一个属性的时候触发')
if self.__dict__.get(item, None):
del self.__dict__[item]
stu = Student()
stu.name = 'zlw' # 设置一个属性值的时候触发
print(stu.noexit) # 访问一个不存在的属性时候触发 , 返回'不存在'
del stu.name # 删除一个属性的时候触发
5.__iter__、__next__
这2个方法用于将一个对象模拟成序列。内置类型如列表、元组都可以被选代,文件对象也可以被选代获取每一行内容。重写这两个方法就可以实现自定义的选代对象。
class MyRange():
def __init__(self,begin,end,step):
self.begin=begin
self.end=end
self.step=step
self.count=0
def __iter__(self):
return self
def __next__(self):
if self.begin <self.end:
self.count=self.begin
self.begin=self.begin+self.step
return self.count
else:
raise stopiteration('已经到达临界')
if __name__=='__main__':
ra=MyRange(1,20,3)
for item in ra:
print(item)
----------------------------------------------------------------------------------------
6.item类和__len__
在深度学习中,我们在封装dataset的时候,一定会重写的两个内置方法,非常重要!!
class Person:
def __getitem__(self,key): # 获取
return self.__dict__[key]
def __setitem__(self,key,value): #设置
self.__dict__[key] = value
def __delitem__(self,key): #删除
self.__dict__.pop(key)
p = Person()
p['a'] = 1
print(p['a'])
del p['a']
print(p['a']) #这里会报KeyError
#使用len()时执行
class Life:
def __init__(self,name,length):
self.name = name
self.length = length
def __len__(self):
return self.length
hsr = Life('hsr',100)
print(len(hsr))
7.__hash__
hash()用于获取一个对象(字符串、数字、对象)的哈希值,不能直接作用于list、set、dict
在hash()最用对象时,所得的结果不仅和对象的内容有关,还和对象的id(),也就是内存地址相关。
hash() 函数的对象字符不管有多长,返回的 hash 值都是固定长度的,也用于校验程序在传输过程中是否被第三方(木马)修改,如果程序(字符)在传输过程中被修改hash值即发生变化,如果没有被修改,则 hash 值和原始的 hash 值吻合,只要验证 hash 值是否匹配即可验证程序是否带木马(病毒)。
#对对象进行hash运算
class Student:
def __init__(self,no,name):
self.no = no
self.name = name
def __hash__(self):
return hash(str(self.no)+self.name)
s = Student(102302,'hsr')
print(hash(s))
8.__eq__
class Life:
def __init__(self,name,length):
self.name = name
self.length = length
def __len__(self):
return self.length
def __eq__(self, other):
return other.length == self.length #重写后,判断的是长度是否相等,如果不重写,因为地址不一样,就不相等
hsr = Life('hsr',100)
ttt = Life('ttt',100)
print(hsr == ttt)
原文地址:https://www.jb51.cc/wenti/3282143.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。