making a class callable in same instance
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Foo(object):
def tick(self):
print("something")
class Bar(object):
def __init__(self):
self.foo = Foo()
def tick(self):
#Here's what I do....
self.foo.tick()
#here's what my goal would be
self.foo()
b = Bar()
b.tick() |
这基本上是我的目标。根据我收集到的信息,我可以将tick函数改为__call__,这将允许我做我想做的事情。其他一些答案说,这将成为对象的一个新实例,这是否意味着它将使用self.foo的内存?或者它会成为一个全新的对象,新实例?还是复制self.foo?
此外,这方面的一些缺点可能会出现,也可能不会出现。对于我程序的一个特定部分,我检查对象是否有一个__call__,以确定我传递的参数是函数还是变量,我不认为我真的想允许调用它(尽管,我认为从技术上讲,类是一个函数)。是否有任何方法可以区分func还有一个可调用的类?
还有什么其他的事情会让你觉得这样做不受欢迎吗(这是一种Python式的工作方式吗?)我的下一个想法是,考虑到以__为前缀的其他变量不能在它们的类之外使用,但这里似乎不是这样。
- 实现__call__不会创建对象的新实例。执行TheClass()创建了一个新实例,但some_instance()只调用__call__。
- 我只是在您没有想到的情况下提到这个——但是,使用上面非常简单的代码,使Bar继承Foo似乎是一个很好的选择——当然,您的用例可能会使它成为一个不好的选择……
将tick(self)改为__call__(self)是正确的解决方案。
这与内存分配无关。所有__call__表示的是python在(对于对象foo使用语法foo()时调用的函数。
对于您以后的问题:要检查某个对象是否为对象,请使用isinstance或issubclass(可能与object类一起使用)。在我看来,这个答案比公认的答案更好,因为"我如何确定某个东西是否是一个函数?"你可能见过的问题。
要使类实例可调用,只需实现一个__call__方法。然后,要调用__call__方法,只需执行以下操作:instance(arg1,arg2,...)—换句话说,调用实例的方式与调用函数的方式相同。
请注意,如果需要,可以使用类上定义的其他方法来别名__call__:
1 2 3 4 5 6 7 8 9 10
| >>> class Foo(object):
... def tick(self):
... print ("something")
... __call__ = tick
...
>>> a = Foo()
>>> a()
something
>>> a.tick()
something |
- 如果要实现一个接受参数的函数,您还可以使用这个别名方法吗?或者它只在函数只有一个参数self时工作?
- @Ajay——应该还能用。
- 我正在尝试使不同的实例具有不同的调用方法。但是,如果我在init_uuuu()中设置了self.uu call_uuu,当我实际调用instance()时,会得到typeerror:callableClass对象不可调用。有没有一种方法可以将"调用"实例设置为不同的实例?
- 您可以拥有_delegate财产,__call__将委托给:def __call__(self): self._delegate()