资讯专栏INFORMATION COLUMN

Python 魔法方法

187J3X1 / 920人阅读

摘要:魔法方法基础如果你想所以你写调用初始化一个实例作为一个字符串的官方表示作为一个字符串作为字节数组作为格式化字符串方法在创建实例后调用如果你想控制创建过程请使用方法按照惯例应该返回一个有效的表达式的字符串方法也被称为你的迭代相关如果你想所以你

Python 魔法方法 基础:
如果你想... 所以,你写... Python调用...
初始化一个实例 x = MyClass() x.__init__()
作为一个字符串的"官方"表示 repr(x) x.__repr__()
作为一个字符串 str(x) x.__str__()
作为字节数组 bytes(x) x.__bytes__()
作为格式化字符串 format(x, format_spec) x.__format__(format_spec)

__init__()方法在创建实例后调用.如果你想控制创建过程,请使用__new__()方法

按照惯例, __repr__() 应该返回一个有效的Python表达式的字符串

__str__()方法也被称为你的print(x)

迭代相关
如果你想... 所以,你写... Python调用...
遍历一个序列 iter(seq) seq.__iter__()
从迭代器中获取下一个值 next(seq) seq.__next__()
以相反的顺序创建一个迭代器 reversed(seq) seq.__reversed__()

__iter__()无论何时创建新的迭代器,都会调用该方法.

__next__()每当你从迭代器中检索一下个值的时候,都会调用该方法

__reversed__()方法并不常见.它需要一个现有序列并返回一个迭代器,该序列是倒序的顺序.

属性
如果你想... 所以,你写... Python调用...
得到一个属性 x.my_property x.__getattribute__("my_property")
获得一个属性 x.my_property x.__getattr__("my_property")
设置一个属性 x.my_property = value x.__setattr__("my_property", value)
阐述一个属性 del x.my_property x.__delattr__("my_property")
列出所有属性和方法 dir(x) x.__dir__()

如果你的类定义了一个__getattribute__()方法,Python将在每次引用任何属性或方法名时调用它.

如果你的类定义了一个__getattr__()方法,Python只会在所有普通地方查找属性后调用它.如果一个实例x定义了一个属性 color, x.color将不会调用x.__getattr__("color"); 它将简单地返回已经定义的x.color值.

__setattr__()只要你为属性指定值,就会调用该方法.

__delattr__()只要删除属性,就会调用该方法.

__dir__()如果您定义一个__getattr__() 或者 __getattribute__() 方法,该方法很有用.通常情况下,调用dir(x)只会列出常规属性和方法.

__getattr__()__getattribute__()方法之间的区别很微妙但很重要.

函数类

通过定义__call__()方法,您可以创建一个可调用类的实例 - 就像函数可调用一样.

如果你想... 所以,你写... Python调用...
来"调用"像函数一样的实例 my_instance() my_instance.__call__()
行为

如果你的类作为一组值的容器 - 也就是说,如果问你的类是否"包含"一个值是有意义的 - 那么它应该定义下面的特殊方法,使它像一个集合一样.

如果你想... 所以,你写... Python调用...
序列的数量 len(s) s.__len__()
否包含特定的值 x in s s.__contains__(s)
字典(映射)
如果你想... 所以,你写... Python调用...
通过它的key来获得值 x[key] x.__getitem__(key)
通过它的key来设置一个值 x[key] = value x.__setitem__(key, value)
删除键值对 del x[key] x.__delitem__(key)
为丢失的key提供默认值 x[nonexistent_key] x.__missing__(nonexistent_key)
数字
如果你想... 所以,你写... Python调用...
x + y x.__add__(y)
x - y x.__sub__(y)
x * y x.__mul__(y)
整除 x / y x.__trueiv__(y)
x // y x.__floordiv__(v)
取余 x % y x.__mod__(y)
整除与取余 divmod(x, y) x.__divmod__(y)
平方 x ** y x.__pow__(y)
左移 x << y x.__lshift__(y)
友移 x >> y x.__rshift__(y)
按位and运算 x & y x.__and__(y)
按位xor或运算 x ^ y x.__xor__(y)
按位or运算 `x y` x.__or__(y)

上述一组特殊方法采用第一种方法:给定x / y,它们提供了一种方法让x说"我知道如何用y整除自己".以下一组特殊方法解决了第二种方法:它们为y提供了一种方法来说"我知道如何成为分母,并将自己整除x".

如果你想... 所以,你写... Python调用...
x + y x.__radd__(y)
x - y x.__rsub__(y)
x * y x.__rmul__(y)
整除 x / y x.__rtrueiv__(y)
x // y x.__rfloordiv__(v)
取余 x % y x.__rmod__(y)
整除与取余 divmod(x, y) x.__rdivmod__(y)
平方 x ** y x.__rpow__(y)
左移 x << y x.__rlshift__(y)
友移 x >> y x.__rrshift__(y)
按位and运算 x & y x.__rand__(y)
按位xor或运算 x ^ y x.__rxor__(y)
按位or运算 `x y` x.__ror__(y)

可是等等!还有更多!如果你正在进行"就地"操作,如x /= 3则可以定义更多特殊的方法.

如果你想... 所以,你写... Python调用...
x + y x.__iadd__(y)
x - y x.__isub__(y)
x * y x.__imul__(y)
整除 x / y x.__itrueiv__(y)
x // y x.__ifloordiv__(v)
取余 x % y x.__imod__(y)
整除与取余 divmod(x, y) x.__idivmod__(y)
平方 x ** y x.__ipow__(y)
左移 x << y x.__ilshift__(y)
友移 x >> y x.__irshift__(y)
按位and运算 x & y x.__iand__(y)
按位xor或运算 x ^ y x.__ixor__(y)
按位or运算 `x y` x.__ior__(y)

还有一些"单个数"数学运算可以让你自己对类似数字的对象进行数学运算.

如果你想... 所以,你写... Python调用...
负数 -x x.__neg__()
正数 +x x.__pos__()
绝对值 abs(x) x.__abs__()
~x x.__invert__()
复数 complex(x) x.__complex__()
整数 int(x) x.__int__()
浮点数 float(x) x.__float__()
四舍五入到最近的整数 round(x) x.__round__()
四舍五入到最近的n位数 round(x, n) x.__round__(n)
最小整数 math.ceil(x) x.__ceil__()
最大整数 math.floor(x) x.__floor__()
截断x到0的最接近的整数 math.trunc(x) x.__trunc__()
数字作为列表索引 a_list[x] a_list[x.__index__()]
比较
如果你想... 所以,你写... Python调用...
等于 x == y x.__eq__(y)
不等于 x != y x.__ne__(y)
小于 x < y x.__lt__(y)
小于等于 x <= y x.__le__(y)
大于 x > y x.__gt__(y)
大于等于 x >= y x.__ge__(y)
布尔 if x: x.__bool__()
序列化
如果你想... 所以,你写... Python调用...
对象副本 copy.copy(x) x.__copy__()
深拷贝 copy.deepcopy(x) x.__deepcopy__()
序列化一个对象 pickle.dump(x, file) x.__getstate__()
序列化一个对象 pickle.dump(x, file) x.__reduce__()
序列化一个对象 pickle.dump(x, file, protocol_version) x.__reduce_ex__(protocol_version)
取出恢复后的状态 x = pickle.load(fp) x.__getnewargs__()
取出恢复后的状态 x = pickle.load(fp) x.__setstate__()
with 语句

with块限定了运行时上下文;在执行with语句时,"进入"上下文,并在执行块中的最后一个语句后"退出"上下文.

如果你想... 所以,你写... Python调用...
进入with语句块 with x: x.__enter__()
退出with语句块 with x: x.__exit__(exc_type, exc_value, traceback)
真正深奥的东西
如果你想... 所以,你写... Python调用...
x = MyClass() x.__new__()
del x x.__del__()
`` x.__solts__()
hash(x) x.__hash__()
x.color type(x).__dict__["color"].__get__(x, type(x))
x.color = "PapayaWhip" type(x).__dict__["color"].__set__(x, "PapayaWhip")
del x.color type(x).__dict__["color"].__del__(x)
isinstance(x, MyClass) MyClass.__instancecheck__(x)
isinstance(C, MyClass) MyClass.__subclasscheck__(C)
isinstance(C, MyABC) MyABC.__subclasshook__(C)

Python正确调用__del__()特殊方法时非常复杂.为了完全理解它,你需要知道Python如何跟踪内存中的对象.这里有一篇关于Python垃圾收集和类析构函数的好文章.你还应该阅读关于弱引用,weakref模块,以及可能的gc模块以获得更好的度量.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/41785.html

相关文章

  • Python “黑魔法” 之 Meta Classes

    摘要:幸而,提供了造物主的接口这便是,或者称为元类。接下来我们将通过一个栗子感受的黑魔法,不过在此之前,我们要先了解一个语法糖。此外,在一些小型的库中,也有元类的身影。 首发于 我的博客 转载请注明出处 接触过 Django 的同学都应该十分熟悉它的 ORM 系统。对于 python 新手而言,这是一项几乎可以被称作黑科技的特性:只要你在models.py中随便定义一个Model的子类,Dj...

    LeoHsiun 评论0 收藏0
  • Python “黑魔法” 之 Encoding & Decoding

    摘要:我可以明确告诉你这不是,但它可以用解释器运行。这种黑魔法,还要从说起。提案者设想使用一种特殊的文件首注释,用于指定代码的编码。暴露了一个函数,用于注册自定义编码。所谓的黑魔法其实并不神秘,照猫画虎定义好相应的接口即可。 首发于我的博客,转载请注明出处 写在前面 本文为科普文 本文中的例子在 Ubuntu 14.04 / Python 2.7.11 下运行成功,Python 3+ 的接...

    邹强 评论0 收藏0
  • python魔法算法详解

    摘要:据说,的对象天生拥有一些神奇的方法,它们总被双下划线所包围,他们是面向对象的的一切。的魔术方法非常强大,然而随之而来的则是责任。 据说,Python 的对象天生拥有一些神奇的方法,它们总被双下划线所包围,他们是面向对象的 Python 的一切。 他们是可以给你的类增加魔力的特殊方法,如果你的对象实现(重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,你...

    孙吉亮 评论0 收藏0
  • 让mysqldump变成并发导出导入的魔法

    摘要:,指定并发导出或导入线程数。默认线程数,默认线程数是个数。注线程数不是越大越好,这里主要的衡量指标是网络带宽磁盘目标库,最好用观察一下。 1. 简介 取名mypumpkin,是python封装的一个让mysqldump以多线程的方式导出库表,再以mysql命令多线程导入新库,用于成倍加快导出,特别是导入的速度。这一切只需要在 mysqldump 或 mysql 命令前面加上 mypum...

    KitorinZero 评论0 收藏0
  • 经验拾忆(纯手工)=> Python__黑魔法__

    摘要:类的继承类继承有三种调用方式,其实是有区别的,听我慢慢道来第一种父类方法参数直接调用第二种方法参数直接调用在谁的类下调用,就找此类对应的下一个就是要继承的第三种方法参数找类名对应的的下一个,就是继承的,一般写本身的类名上下文管理器上下文管理 类的继承 类继承有三种调用方式,其实是 有区别 的,听我慢慢道来 class A: def say(self, name): ...

    tulayang 评论0 收藏0

发表评论

0条评论

187J3X1

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<