使类在同一实例中可调用
Posted
技术标签:
【中文标题】使类在同一实例中可调用【英文标题】:making a class callable in same instance 【发布时间】:2013-01-13 04:55:42 【问题描述】: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()
这基本上就是我的目标。根据我收集到的信息,我可以将刻度函数更改为__call__
,这样我就可以做我想做的事了。其他几个答案说这将创建一个对象的新实例,这是否意味着它将使用 self.foo 的内存?还是会创建一个全新的对象,新实例化?或者复制一份 self.foo?
我还想到了一些可能会或可能不会表现出来的缺点。对于我程序的特定部分,我检查对象是否有 __call__
以确定我传递的参数是函数还是变量,我真的不认为我会允许它被调用(即使,我认为该类在技术上将是一个函数。)有没有办法区分函数和可调用类?
还有什么东西会让这样做不受欢迎(这是一种 Python 的工作方式吗?)?我的下一个想法是,考虑到其他以__
为前缀的变量不能在他们的班级之外使用,但这里似乎并非如此。
【问题讨论】:
实现__call__
将不会创建对象的新实例。执行TheClass()
会创建一个新实例,但some_instance()
只是调用__call__
。
我只是在你没有想到的情况下提到这一点 -- 但是,使用上面非常简单的代码,让 Bar
继承自 Foo
似乎是一个不错的选择-- 当然,您的用例可能不是一个好选择...
【参考方案1】:
将tick(self)
更改为__call__(self)
是正确的解决方案。
这与内存分配无关。所有__call__
表示的是当您使用(对于对象foo
)语法foo()
时Python 调用的函数。
对于您后面的问题:要检查某物是否是对象,请使用 isinstance
或 issubclass
(可能与 object
类一起使用)。在我看来,this answer 比公认的“我如何确定某物是否是函数?”更好。你可能见过的问题。
【讨论】:
【参考方案2】:要使类实例可调用,您需要做的就是实现__call__
方法。然后,要调用__call__
方法,您只需:instance(arg1,arg2,...)
——换句话说,您调用实例的方式与调用函数的方式相同。
请注意,如果需要,您可以使用在类上定义的其他方法为 __call__
起别名:
>>> class Foo(object):
... def tick(self):
... print ("something")
... __call__ = tick
...
>>> a = Foo()
>>> a()
something
>>> a.tick()
something
【讨论】:
如果你要实现一个带参数的函数,你还能使用这种别名方法吗?还是仅在函数只有一个参数时才起作用self
我正在努力让不同的实例有不同的 call 方法。但是,如果我在 init__() 中设置 self.__call__,当我实际调用 instance() 时,我会得到 TypeError: 'CallableClass' object is not callable。有没有办法以不同的方式设置 __call 实例到实例?
您可以拥有一个_delegate
属性,__call__
将委托给:def __call__(self): self._delegate()
以上是关于使类在同一实例中可调用的主要内容,如果未能解决你的问题,请参考以下文章