关于python:在同一个实例中使一个类可调用

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式的工作方式吗?)我的下一个想法是,考虑到以__为前缀的其他变量不能在它们的类之外使用,但这里似乎不是这样。


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

这与内存分配无关。所有__call__表示的是python在(对于对象foo使用语法foo()时调用的函数。

对于您以后的问题:要检查某个对象是否为对象,请使用isinstanceissubclass(可能与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