我应该直接使用python魔术方法吗?

Hyp*_*837 7 python magic-methods

我从一个人那里听说你不应该直接使用魔法方法。我认为在某些用例中,我必须直接使用魔术方法。这么有经验的开发者,我应该直接使用python魔术方法吗?

Sor*_*ary 7

我打算展示直接使用魔术方法的一些好处:

1-可读性:

使用内置函数len()比它相关的魔法/特殊方法更具可读性__len__()。想象一下,一个只有魔法方法而不是内置函数的源代码……成千上万的下划线……


2- 比较运算符:

class C:
    def __lt__(self, other):
        print('__lt__ called')

class D:
    pass

c = C()
d = D()

d > c
d.__gt__(c)
Run Code Online (Sandbox Code Playgroud)

我没有__gt__为这两个类实现,但是d > c当 python 看到该类D没有时__gt__,它会检查类是否C实现了__lt__。确实如此,因此我们获得'__lt__ called'了输出,而d.__gt__(c).


3- 额外检查:

class C:
    def __len__(self):
        return 'boo'

obj = C()
print(obj.__len__())  # fine
print(len(obj))       # error
Run Code Online (Sandbox Code Playgroud)

或者:

class C:
    def __str__(self):
        return 10

obj = C()
print(obj.__str__())  # fine
print(str(obj))       # error
Run Code Online (Sandbox Code Playgroud)

如您所见,当 python 隐式调用这些魔术方法时,也会进行一些额外的检查


4-这是最不重要的,但使用len()内置数据类型,例如str与以下相比可以提高一点速度__len__()

from timeit import timeit

string = 'abcdefghijklmn'

print(timeit("len(string)", globals=globals(), number=10_000_000))
print(timeit("string.__len__()", globals=globals(), number=10_000_000))
Run Code Online (Sandbox Code Playgroud)

输出:

0.5442426
0.8312854999999999
Run Code Online (Sandbox Code Playgroud)