python魔术方法(一)
所谓的魔术方法就是让用户客制化类的方法,常常是python中开头有两个下划线的方法。
__new__()
new是创建一个类的过程
class A:def __new__(cls,x):print("__new__")return super().__new__(cls)
由于new函数是建立了一个对象,所以必须返回一个对象
__init__()
init是初始化一个类的过程
class A:def __new__(cls,x):print("__new__")return super().__new__(cls)def __init__(self,x):print("__init__")
这个我们就很常用了
__del__
对象被释放的时候你想做什么,但是吧,python的释放是一个复杂的机制,由解释器控制的,也许这个对象被引用到0的时候被释放了,也有可能被垃圾回收机制释放了,而且这个释放可能在任意地方发生,这个释放是不受控制的,
class A:def __new__(cls,x):print("__new__")return super().__new__(cls)def __init__(self,x):print("__init__")def __del__(self):print("__del__")
这个__del__
函数和关键字del
没什么关系,del
只是让对象少一个引用。
__repr__
返回对象的字符串表示
class A:def __repr__(self):return "A repr"print(repr(A()))
__str__
返回对象的字符串表示,与上面的方法不同的点在于,本方法更多的是返回人类更好理解的信息,上一个方法返回的信息更为详细复杂。
class A:def __repr__(self):return "A repr"
print(str(A()))
如果我们没有定义这个函数,直接去调用呢,也可以,因为python会自动的调用 __repr__
的返回值。
__format__
当你尝试用某种格式来打印一个类的时候就会用到这个函数
class A:def __format__(self,spec):if spec == "x":return "0xA"return "A"print("{}".format(15))
print("{:b}".format(15))
print("{:x}".format(15))print("{A()}")
print("{A():x}")
__bytes__
class A:def __bytes__(self):print("__bytes__called")return bytes([0,1])print(bytes(A()))
当你尝试用自己类去建立一个bytes
的时候,他应该返回什么,其实除非是客制化一个类的bytes
表示,否则也是用不上的。
__eq__
改变比较的逻辑,判断两个对象是否相等
class Date:def __init__(self,num):self.num = numdef __eq__(self,others):return self.num == other.num
为什么不能直接判断呢?,就像下面这样
class Date:def __init__(self,num):self.num = numa = Date(1)
b = Date(1)
print(a == b)
因为如果没定义这些方法的话,a == b
就会被翻译为 a is b
,这样的话就是比较两个对象的地址是否相等。咦~~,是不是有点像运算符重载。
而且理论上是不是比较方法必须返回bool
值,但是python是没有对这个做任何限制的,你可以返回任何东西。这个有什么用呢,如果你比较两个向量的话,就可以返回一个向量,这个向量表示对应位置的值是否相等。
__ne__
如果我们没有单独的定义不等的魔术方法的话,python会将__eq__
的结果取反
class Date:def __init__(self,num):self.num = numdef __ne__(self,others):return self.num != other.num
__gt__
等于或者不等于是有默认实现的,如果我们没有定义的话就会调用 is
,但是大于小于就没有默认调用了
class Date:def __init__(self,num):self.num = numdef __gt__(self,others):return self.num > other.num
这里有个有趣的事情
a = Date(2)
b = Date(3)
print(a < b)
返回了结果True
,不对啊,这个类没有小于的方法啊,其实这里我们的python又默认了大于和小于是一对,这里就调用了 b.__gt__(a)
。因为在语义上a小于b和b大于a是一致的。
__lt__
小于函数,这里的优先级大于上面我们讲的默认大于。
class Date:def __init__(self,num):self.num = numdef __lt__(self,others):return self.num > other.num
但是但是但是!!!这个优先级是一定的嘛?并不是,如果我们比较的不是同一个类的话,那我们就会遇到麻烦,啥?比较的还能不是同一个类??是的,通过继承可以有衍生类啊,如果是和衍生类进行比较的话,优先调用的就父类。大部分情况下就是调用左边的那个类的方法,左边没有就是右边的,如果右边的类是左边的类的子类,那么就优先室友右边的类的函数。
__ge__
大于等于,大体和上面一致,python中不会对大于等于这个运算做任何推测
__le__
小于等于,大体和上面一致,python中不会对大于等于这个运算做任何推测
__hash__
hash
散列函数有自己的默认实现,如果我们需要客制化才需要用hash
函数。hash
的基本定义在于两个类如果相等那么这两个类的hash
必然相等。
这个函数要求必须返回一个整数,而且两个对象相等的话他们的hash
值必须相等。
class A:def __init__(self,num1,num2):self.num1 = num1self.num2 = num2def __hash__(self):return 2
上面这个方法是可以的,但是很蠢,因为会造成非常严重的哈希碰撞。可以通过把对象的核心属性组成一个tuple的方式,求tuple的hash值作为对象的hash值。
class A:def __init__(self,num1,num2):self.num1 = num1self.num2 = num2def __hash__(self):return hash((self.num1,self.num2))
__bool__
调用对象的bool方法的默认方法。
class A:def __init__(self,num1,num2):self.num1 = num1self.num2 = num2def __bool__(self):if self.num1 > 10:return Truea = A(11)
if a :print("OK")
python魔术方法(一)相关推荐
- python 魔术方法
python 魔术方法 常用魔术方法 魔术方法就是一个类的特殊方法,和普通方法唯一的不同时,普通方法需要调用!而魔术方法由系统自动调用. 1.__init__ 初始化魔术方法 触发时机:初始化对象时触 ...
- 【Python魔术方法】py复习
Python魔术方法 __init__ 类似于构造器 #__init__ magic class Human:def __init__(self, name):#print('init exec')s ...
- Python 魔术方法指南
http://pycoders-weekly-chinese.readthedocs.org/en/latest/issue6/a-guide-to-pythons-magic-methods.htm ...
- python魔术方法由谁定义_Python的魔术方法
魔术方法就是在定义的类中定义一些"不一般"的方法,使类的使用更方便.完善.健壮,是python特有的方法,一般都是前后包含两个下划线__的方法称为魔术方法,例如__new__. 基 ...
- [转载] 【python魔术方法】迭代器(__iter__和__next__)
参考链接: Python __iter __()和__next __()| 将对象转换为迭代器 文章目录 `__iter__` 和 `__next__`真正的迭代器总结 python里面有很多的以__ ...
- python魔术方法abstract_python学习之面向对象高级特性和魔术方法
01_property商品应用.py 分页显示是一种非常常见的浏览和显示大量数据的方法,属于web编程中最常处理的事件之一. 类属性应用需求: 对于京东商城中显示电脑主机的列表页面,每次请求不可能把数 ...
- python魔术方法是什么_Python常用魔术方法
什么是魔术方法? 在Python中,所有以双下划线__包起来的方法,统称为Magic Method(魔术方法),它是一种的特殊方法,普通方法需要调用,而魔术方法不需要调用就可以自动执行. 魔术方法在类 ...
- python——魔术方法
特殊方法 1.__init__魔术方法 初始化魔术方法 2.__new__魔术方法 对象初始化: 先执行 _ new _ :分配内存空间,并返回构建好的对象(的地址) 再执行 _ init _ ...
- python魔术方法(进阶)斐波那契数列
文章目录 特殊属性 查看属性 实例化 可视化 hash bool 运算符重载应用场景 容器相关方法 可调用对象 上下文管理 上下文管理的安全性 方法的参数 contextlib.contextmana ...
最新文章
- 如何利用图像预处理提高OCR的准确性?
- Mybatis面试常见问题
- RHEL7.0 DNS服务配置
- mybatis 时间_开发工具:Mybatis.Plus.插件三种方式的逆向工程
- html调出手机系统设置,手机怎么打开路由器设置界面?
- 构建之法阅读笔记之速读篇
- kafka控制器,复制与存储小结
- 关于oracle自动编号
- 惊恐!电脑竟然会使用计谋了!——第二局感悟
- 基于禁忌搜索算法的TSP搜索算法
- 官方标配,吊炸天的 Linux 可视化管理工具,必须推荐给你
- android多个声音输出,Android新增一个音频类型及双音频输出的实现
- 就业和工作?毕业生何去何从?
- 赵伟国回应华为“平衡者”标签:做个老二、老三也可以
- 外汇和股票有什么区别啊?
- jQuery中toggle与slideToggle以及fadeToggle之间的不同
- 激活黑群晖Synology Active Backup for Business,黑群晖系统备份软件激活,亲测有效
- Zookeeper出现Error contacting service. It is probably not running问题
- 缠中说禅《论语》详解:给所有曲解孔子的人
- 一名开源工程师的自白
热门文章
- [小白入门]SEO优化是什么意思?4步骤掌握SEO网站优
- 机器人之Cartographer
- iOS通讯录复制的手机号码字符串多了奇怪的unicode码\u0000202d-\u0000202c
- 软件设计分为前端后端吗
- 【软件技巧】Transmission跳过检验(跳检)方法,适用于全平台
- 推广那些坑,做好渠道组合拳!
- Ubuntu 18.04 安装 onedrive
- Word及Autocad中中文字号与字体大小的关系
- dw中css面板在哪,请问下美工设计师:1、怎么在DWCS5设计面板里面找到CSS代码? 爱问知识人...
- 平价蓝牙耳机里面性价比高推荐?隐形蓝牙耳机超小推荐