对商业智能 BI, 大数据分析挖掘, 机器学习, python,R 等数据领域感兴趣的同学加微信: tstoutiao, 并注明消息来源, 邀请你进入数据爱好者交流群, 数据爱好者们都在这儿.
作者: 小新 python 入门到放弃
公众号: 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__方法. 就不多说了.
Python 爱好者社区历史文章大合集:
Python 爱好者社区历史文章列表 (每周 append 更新一次)
福利: 文末扫码立刻关注公众号,"Python 爱好者社区", 开始学习 Python 课程:
关注后在公众号内回复 "课程" 即可获取:
小编的转行入职数据科学 (数据分析挖掘 / 机器学习方向)[最新免费]
小编的 Python 入门免费视频课程!!!
小编的 Python 快速上手 matplotlib 可视化库!!!
崔老师爬虫实战案例免费学习视频.
陈老师数据分析报告制作免费学习视频.
玩转大数据分析! Spark2.X+Python 精华实战课程免费学习视频.
来源: http://www.jianshu.com/p/2558bf1314d1