赋值与定义 Python 魔术方法

kg5*_*583 24 python class magic-methods assign

考虑以下令人厌恶的类:

class MapInt:
    __call__ = int

    def __sub__(self, other):
        return map(self, other)

    __add__ = map
Run Code Online (Sandbox Code Playgroud)

然后可以map(int, lst)通过调用MapInt() - lst,即

assert list(MapInt() - ['1','2','3'])) == [1,2,3]    # passes
Run Code Online (Sandbox Code Playgroud)

然而,加法就不那么合作了:

assert list(MapInt() + ['1','2','3'])) == [1,2,3]    # TypeError: map() must have at least two arguments.
Run Code Online (Sandbox Code Playgroud)

这个奇怪的现象可以通过直接调用magic方法来解决:

assert list(MapInt.__add__(MapInt(), ['1','2','3']))   == [1,2,3]    # passes
assert list(MapInt().__add__(MapInt(), ['1','2','3'])) == [1,2,3]    # passes
Run Code Online (Sandbox Code Playgroud)

所以我的问题是,什么给出了?直接赋值__add__似乎“丢弃”了self参数,但是调用方法本身或以标准方式定义它效果很好。

sj9*_*126 19

实例方法的转换在Python数据模型中描述(重点是我的):

请注意,每次从实例检索属性时,都会发生从函数对象到实例方法对象的转换 [...]另请注意,此转换仅发生在用户定义的函数中;其他可调用对象(以及所有不可调用对象)无需转换即可检索

由于map是内置函数,而不是用户定义函数,因此没有转换为实例方法,因此self不添加参数。

  • 很棒的发现,但这很奇怪而且不一致。我认为任何非数据描述符都可以。 (2认同)