面向对象中的双下方法
1、__str__与__repr__方法
class Animal: def __init__(self,name,age): self.name = name self.age = age def f(self): print("这是父类的方法") class Persion(Animal): country = "chinese" def __init__(self,name,age,sex): Animal.__init__(self,name,age) self.sex = sex def eat(self): print("这是子类中的方法") # def __str__(self): # return "这是子类中的str" def __repr__(self): return "这是子类中的repr" a = Persion("小明",18,"sex") print(a) print(str(a)) print(repr(a)) print(a.__repr__()) print(a.__str__()) print('%s'%a) print('%r'%a)
这两个双下方法可以改变字符串的显示,打印一个对象,本质上是调用__str__方法,如果没有找到,就找__repr__方法,再找不到,就调用父类中的,__repr_是__str__的备胎,__str__不是__repr_的,再父类中有一个__str__方法,一旦调用,就返回调用这个方法的对象的内存地址。调用__str__一共有四种方法。
2、__del__析构函数 再删除一个对象之前进行一个收尾工作
注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
class Persion(Animal): country = "chinese" def __init__(self,name,age,sex): Animal.__init__(self,name,age) self.sex = sex def eat(self): print("这是子类中的方法") # def __str__(self): # return "这是子类中的str" def __repr__(self): return "这是子类中的repr" def __del__(self): print("我要开始删除对象了") a = Persion("小明",18,"sex") del a print(a)
del既执行了这个方法,也删除了变量,先执行__del__,在执行删除,再删除一个对象之前做收尾工作。
3、__call__ 对象后面加括号执行 即:对象() 或者 类()()
class Foo(): def __call__(self, *args, **kwargs): print("打印call函数") a = Foo() a() Foo()()
4、__new__构造函数 实例化对象
调用__init__方法之前,首先调用__new__方法,返回一个实例self ,若__new__方法没有返回当前类cls的实力,那么init方法不会被调用。因为类每一次实例化产生的过程都是通过__new__来控制的,所以我们可以通过__new__方法简单的实现实例化。
通过__new__方法方法实例化一个对象,并开辟一块地址空间,__new__方法return实例,init方法就不会被调用
class Animal: def __init__(self,name,age): self.name = name self.age = age def f(self): print("这是父类的方法") class Persion(Animal): country = "chinese" _instance = False def __init__(self,name,age,sex): Animal.__init__(self,name,age) self.sex = sex print("init方法") def eat(self): print("这是子类中的方法") def __new__(cls, *args, **kwargs): if cls._instance : return cls._instance cls._instance = object.__new__(Persion) return cls._instance a = Persion("小明",18,"sex") a.cloth = "小花袄" print(a) print(a.__dict__) b = Persion("小红",19,"nv") print(b) print(b.__dict__) print(a.__dict__)
单例模式只会产生一个实例,就是第一个实例,之后的实力化,相当于对之前对象的属性重新命名。
5、__eq__方法 父类中的eq方法默认比较的是内存地址
class Animal: def __init__(self,name,age): self.name = name self.age = age def f(self): print("这是父类的方法") class Persion(Animal): def __init__(self,name,age,sex): Animal.__init__(self,name,age) self.sex = sex def eat(self): print("这是子类中的方法") def __eq__(self,other): if self.name == other.name: return True else : return False a = Persion("小明",18,"sex") b =Persion("小明",43,"女") print(a == b)
通过比较名字来判断是不是相等
应用:100个学生记录,其中有的名字和性别相同,年龄不同,认为名字和性别相同就是同一个人,根据这个去重
6、__delitem__ __delattr__ __setitem__ __getitem__
class Foo: def __init__(self,name): self.name=name def __getitem__(self, item): print("执行getitem方法了") # print(self.__dict__[item]) return None def __setitem__(self, key, value): print("执行setitem方法了") self.__dict__[key]=value def __delitem__(self, key): print('del obj[key]时,我执行') self.__dict__.pop(key) def __delattr__(self, item): print('del obj.key时,我执行') self.__dict__.pop(item) f1=Foo('sb') f1['age']=18 f1['age1']=19 del f1.age1 del f1['age'] f1['name']='alex' print(f1.__dict__) print(f1["agge"])
I can feel you forgetting me。。 有一种默契叫做我不理你,你就不理我