python 在python中使对象可调用的问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1705928/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Issue with making object callable in python
提问by kjshim
I wrote code like this
我写了这样的代码
>>> class a(object):
def __init__(self):
self.__call__ = lambda x:x
>>> b = a()
I expected that object of class a should be callable object but eventually it is not.
我希望 a 类的对象应该是可调用对象,但最终不是。
>>> b()
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
b()
TypeError: 'a' object is not callable
>>> callable(b)
False
>>> hasattr(b,'__call__')
True
>>>
I can't understand why. Please help me.
我不明白为什么。请帮我。
采纳答案by Alex Martelli
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).
特殊方法是在被操作的对象的类型(例如,类)上查找的,而不是在特定实例上查找的。想一想:否则,如果一个类定义__call__
了例如,当这个类被调用时,__call__
应该被调用......真是一场灾难!但幸运的是,特殊方法改为查找类的类型,AKA 元类,一切都很好(“遗留类”在这方面有非常不规则的行为,这就是为什么我们都更喜欢使用新样式的方法——这是 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.
你就在那里。当然,在这种情况下这会很愚蠢,因为每个实例都以相同的“所谓的每个实例” (!) 结束__call__
,但是如果您真的需要在每个实例的基础上进行覆盖,它会很有用。
回答by John La Rooy
__call__
needs to be defined on the class, not the instance
__call__
需要在类上定义,而不是在实例上
class a(object):
def __init__(self):
pass
__call__ = lambda x:x
but most people probably find it more readable to define the method the usual way
但大多数人可能会发现以通常的方式定义方法更具可读性
class a(object):
def __init__(self):
pass
def __call__(self):
return self
If you need to have different behaviour for each instance you could do it like this
如果您需要为每个实例设置不同的行为,您可以这样做
class a(object):
def __init__(self):
self.myfunc = lambda x:x
def __call__(self):
return self.myfunc(self)
回答by Anonymous
What about this? Define a base class AllowDynamicCall:
那这个呢?定义一个基类 AllowDynamicCall:
class AllowDynamicCall(object):
def __call__(self, *args, **kwargs):
return self._callfunc(self, *args, **kwargs)
And then subclass AllowDynamicCall:
然后子类 AllowDynamicCall:
class Example(AllowDynamicCall):
def __init__(self):
self._callfunc = lambda s: s