Python基础(面向对象编程)
类的内置方法 补充: 其实比如str()这个内置函数,都是在内部调用__str__方法。 之所以提供str()这种方法大概是更简洁吧,有兴趣的可以去看一下源码。 str(123456)实际上是123456.__str__() 实例: a = 123456 b = str(123456) c = a.__str__ print(b) # 输出123456,看不出是字符串类型,你可以type()下 print(c) # 输出一个内存地址,也就是存放这个字符串的内存地址 print(c()) # 输出123456,用一个内存地址加上一个括号就是执行 print(repr(b)) # 利用repr方法输出 '123456',可以看出是字符串类型,同时你也可以type() print(repr(c())) # 同上,输出 '123456' __str__ class A: def __str__(self): return '我是__str__方法' a = A() print(a) 输出:我是__str__方法 你会觉得不可思议吧,但是确确实实是这样,当我们输出a的时候,实际上是输出a.__str__()方法,友谊之前我们没有写这个方法,所以就会调用object中的__str__方法,因为所有没有继承的类,默认是继承object类的,在子类中没有找到__str__方法就会去父类object中找。 列表实例化输出: list = [1,2,3,4,5] print(list) #那么这里为什么会直接输出一个列表,而不是一个内存地址,实际上就是重构了__str__方法。 注:返回值必须为字符串类型 __repr__ class Person: def __init__(self,name): self.name = name def __repr__(self): return self.name p = Person('张三') print(repr(p)) # 输出 张三 print('我的名字是%r'%p) # 输出 我的名字是张三 %r就是调用的__repr__()方法,同理%s?你应该懂吧。如果我们不写repr方法,它就会调用父类的方法,会输出一个内存地址。 注:当我们在类中写了repr方法,没有写str方法,我们再次输出str(Person)他不会输出内存地址,会输出repr中的内容,我们理解为他找不到str方法就会找repr方法,repr方法再没有就会输出内存地址,但是反过来不行。(莫名的备胎)这个repr方法也必须返回字符串。 __del__ class A: def __init__(self,name): self.name = name def __del__(self): print('执行__del__方法') a = A('张三') del a.name print(a.name) 输出: 'A' object has no attribute 'name' 执行__del__方法 报错了,说明删除了name这个属性,并且执行力__del__中的方法。和上面两个不一样。 注:放我们调用完这个一会执行__del__方法,但是没有删除变量。python这个方法内部有个引用计数机制, 当计数为0的时候,就会删除这个属性。来释放内存。 实例: class A: def __init__(self,name): self.name = name def __del__(self): print('执行__del__方法') a = A('张三') import time time.sleep(1) print(a.name) 输出: 张三 执行__del__方法 可以看到,我们并没有调用__del__方法,但是再调用完之后会自动调用这个方法。并且看一下执行顺序,也就是说,先输出,再调用__del__方法。也就是说先执行__del__中的方法,再进行删除,也就是说我们可以在__del__写一些收尾工作,比如f.close()。 __call__ class A: def __call__(self): print('执行了__call__方法') a = A() a() 输出:执行了__call__方法 也就是a()就是执行了__call__方法。 __getitem__ class A: def __init__(self,name,age): self.name = name self.age = age def __getitem__(self,item): return self.__dict__[item] a = A('张三',18) print(a['name']) 输出:张三 我们实例化之类后,a['name'],就是调用内置方法__getitem__中的内容。 __setitem__ class A: def __init__(self,name,age): self.name = name self.age = age def __setitem__(self,key,value): self.__dict__[key] = value a = A('张三',18) a['sex'] = '男' print(a.sex) 输出:男 也同样,当我们a['sex'] = '男'的时候,调用的是 __setitem__方法。 __delitem__ class A: def __init__(self,name,age): self.name = name self.age = age def __delitem__(self,key): del self.__dict__[key] a = A('张三',18) del a['name'] 这样就删除了,其实我会觉得像删除不是有方法吗,这种方法是以将对象以字典的形式查,那么对于字典和列表你可能又有了新的认识。在object中对应的是__delattr__方法。 __new__ 我们知道__init__是在实例化的时候就会执行,在他之前会执行__new__方法。 class A: def __init__(self,name,age): self.name = name self.age = age def __new__(cls,*args,**kwargs): return object.__new__(A,*args,**kwargs) __new__可以决定调用哪个类的_init_方法,如果有两个类,并且是继承关系,就可以选择调用父类的__init__方法,__init__的self就是__new__实例化的结果。有兴趣的可以去了解一下。 __eq__ class A: def __init__(self,name): self.name =name def __eq__(self,other): return self == other a = A('张三') b = A('张三') print(a==b) 返回False,==是调用了__eq__方法,修改成: def __eq__(self,other): return True 就会返回True,但是也不能这样写是吧,我们判断名字相等就让他返回True def __eq__(self,other): if self.name == other.name: return True else: return False 即可。 __hash__ 在hash()一个类的时候,就会执行__hash__方法。就不多说了。 原文发布时间为:2018-11-29 本文作者:小新python入门到放弃 本文来自云栖社区合作伙伴“Python爱好者社区”,了解相关信息可以关注“python_shequ”微信公众号