Issue with making object callable in python

后端 未结 3 1573
被撕碎了的回忆
被撕碎了的回忆 2021-02-05 06:31

I wrote code like this

>>> class a(object):
        def __init__(self):
            self.__call__ = lambda x:x

>>> b = a()

I

3条回答
  •  余生分开走
    2021-02-05 07:10

    Special methods are looked up on the type (e.g., class) of the object being operated on, not on the specific instance. Think about it: otherwise, if a class defines __call__ for example, when the class is called that __call__ should get called... what a disaster! But fortunately the special method is instead looked up on the class's type, AKA metaclass, and all is well ("legacy classes" had very irregular behavior in this, which is why we're all better off with the new-style ones -- which are the only ones left in Python 3).

    So if you need "per-instance overriding" of special methods, you have to ensure the instance has its own unique class. That's very easy:

    class a(object):
        def __init__(self):
            self.__class__ = type(self.__class__.__name__, (self.__class__,), {})
            self.__class__.__call__ = lambda x:x
    

    and you're there. Of course that would be silly in this case, as every instance ends up with just the same "so-called per-instance" (!) __call__, but it would be useful if you really needed overriding on a per-individual-instance basis.

提交回复
热议问题