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__ (下个部分会介绍),乃至使用动态生成的属性,以实现类的交互式使用,那么这个魔法方法是必不可少的。

 

posted @ 2021-04-29 13:41  薄荷味日记  阅读(66)  评论(0编辑  收藏  举报