21
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__确定我传递的参数是函数还是变量,并且我真的不认为我希望允许调用它(尽管如此,我认为该类在技术上将是一个函数。)有没有办法区分函数和可调用类?

还有什么其他的东西会让这样做不受欢迎(这是一种pythonic的工作方式吗?)?我的下一个想法是,鉴于__不能在他们的班级之外使用其他以前缀为前缀的变量,但这里似乎并非如此。

4

2 回答 2

26

更改tick(self)__call__(self)是正确的解决方案。

这与内存分配无关。一切都__call__表示当您使用(对于对象foo)语法时 Python 调用的函数foo()

对于您以后的问题:检查某物是否是对象,请使用isinstanceor issubclass(可能与object类一起使用)。在我看来,这个答案比“如何确定某物是否是函数?”的公认答案更好。您可能已经看到的问题。

于 2013-01-29T15:14:01.227 回答
22

要使类实例可调用,您需要做的就是实现一个__call__方法。然后,要调用该__call__方法,您只需: instance(arg1,arg2,...)-- 换句话说,您调用实例的方式与调用函数的方式相同。

请注意,如果需要,您可以__call__使用在类上定义的其他方法进行别名:

>>> class Foo(object):
...     def tick(self):
...         print ("something")
...     __call__ = tick
... 
>>> a = Foo()
>>> a()
something
>>> a.tick()
something
于 2013-01-29T15:17:41.107 回答