python 内置魔法方法
运算符重载
定义一个Vector类,能够实现任意维向量的加法运算(类似numpy中的向量运算)。
例如,测试代码中分别针对三维向量和二维向量的加法运算:
(1,3,6)+(2,4,3)=(3,7,9)(1,3,6)+(2,4,3)=(3,7,9)
(1,3)+(4,1)=(5,4)(1,3)+(4,1)=(5,4)
提示:重写python内置的魔法方法 __add__
和__repr__
魔法方法,我只知道 __init__ 啊啊!!!__add__我有看到过,但_repr__ 是什么啊。遇事不决,先谷歌。
参考文章 : https://pyzh.readthedocs.io/en/latest/python-magic-methods-guide.html 写的很nice 点一颗星。
构造方法:
- __new__(cls, [...])
- 对象实例化时第一个调用的方法,它只取下 cls 参数,并把其他参数传给 __init__。
- __init__(cls, [...])
- 类的初始化方法。它获取任何传给构造器的参数(比如我们调用 x = SomeClass(10, ‘foo’) , __init__ 就会接到参数 10 和 ‘foo’ 。 __init__在Python的类定义中用的最多。
- __del__(cls, [...])
- __new__和_init__ 是对象的构造器,__del__是对象的销毁器。它并非实现了语句 del x ,因此该语句不等于 x.__del__()。
- 当python 解释器退出但对象任然存活的时候, __del__ 并不会执行。所以养成一个手工清理的好习惯是很重要的,比如及时关闭连接。
from os.path import join class FileObject: '''文件对象的装饰类,用来保证文件被删除时能够正确关闭。''' def __init__(self, filepath='', filename='sample.txt'): # 使用读写模式打开filepath中的filename文件 self.file = open(join(filepath, filename), 'r+') def __del__(self): self.file.close() del self.file test_file = FileObject(filename="test.txt") for line in test_file.file: print(line.strip())
比较操作符:
- __cmp__(self, other)
- 是所有比较魔法方法中最基础的一个,它实际上定义了所有比较操作符的行为(<,==,!=,等等),但是它可能不能按照你需要的方式工作(例如,判断一个实例和另一个实例是否相等采用一套标准,而与判断一个实例是否大于另一实例采用另一套)。 __cmp__ 应该在 self < other 时返回一个负整数,在 self == other 时返回0,在 self > other 时返回正整数。最好只定义你所需要的比较形式,而不是一次定义全部。 如果你需要实现所有的比较形式,而且它们的判断标准类似,那么 __cmp__ 是一个很好的方法,可以减少代码重复,让代码更简洁。
- __eq__(self, other)
- 定义等于操作符(==)的行为。
- __ne__(self, other)
- 定义不等于操作符(!=)的行为。
- __lt__(self, other)
- 定义小于操作符(<)的行为。
- __gt__(self, other)
- 定义大于操作符(>)的行为。
- __le__(self, other)
- 定义小于等于操作符(<)的行为。
- __ge__(self, other)
- 定义大于等于操作符(>)的行为。
class Word(str): '''单词类,按照单词长度来定义比较行为''' def __new__(cls, word): # 注意,我们只能使用 __new__ ,因为str是不可变类型 # 所以我们必须提前初始化它(在实例创建时) if ' ' in word: print "Value contains spaces. Truncating to first space." word = word[:word.index(' ')] # Word现在包含第一个空格前的所有字母 return str.__new__(cls, word) def __gt__(self, other): return len(self) > len(other) def __lt__(self, other): return len(self) < len(other) def __ge__(self, other): return len(self) >= len(other) def __le__(self, other): return len(self) <= len(other)
数值操作符
- 一元操作符
- 常见算数操作符
- 反射算数运算符
- 增强赋值运算符
- 类型转换操作符
类的表示
-
__str__(self)
定义对类的实例调用 str() 时的行为。
-
__repr__(self)
定义对类的实例调用 repr() 时的行为。 str() 和 repr() 最主要的差别在于“目标用户”。 repr() 的作用是产生机器可读的输出(大部分情况下,其输出可以作为有效的Python代码),而 str() 则产生人类可读的输出。
-
__unicode__(self)
定义对类的实例调用 unicode() 时的行为。 unicode() 和 str() 很像,只是它返回unicode字符串。注意,如果调用者试图调用 str() 而你的类只实现了 __unicode__() ,那么类将不能正常工作。所有你应该总是定义 __str__() ,以防有些人没有闲情雅致来使用unicode。
-
__format__(self)
定义当类的实例用于新式字符串格式化时的行为,例如, “Hello, 0:abc!”.format(a) 会导致调用 a.__format__(“abc”) 。当定义你自己的数值类型或字符串类型时,你可能想提供某些特殊的格式化选项,这种情况下这个魔法方法会非常有用。
-
__hash__(self)
定义对类的实例调用 hash() 时的行为。它必须返回一个整数,其结果会被用于字典中键的快速比较。同时注意一点,实现这个魔法方法通常也需要实现 __eq__ ,并且遵守如下的规则: a == b 意味着 hash(a) == hash(b)。
-
__nonzero__(self)
定义对类的实例调用 bool() 时的行为,根据你自己对类的设计,针对不同的实例,这个魔法方法应该相应地返回True或False。
-
__dir__(self)
定义对类的实例调用 dir() 时的行为,这个方法应该向调用者返回一个属性列表。一般来说,没必要自己实现 __dir__ 。但是如果你重定义了 __getattr__ 或者 __getattribute__ (下个部分会介绍),乃至使用动态生成的属性,以实现类的交互式使用,那么这个魔法方法是必不可少的。