【问题标题】: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 似乎是一个不错的选择-- 当然,您的用例可能不是一个好选择...

标签: python class callable


【解决方案1】:

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

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

对于您后面的问题:要检查某物是否是对象,请使用 isinstanceissubclass(可能与 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()
    猜你喜欢
    • 2015-12-04
    • 2020-12-13
    • 2018-07-17
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 2015-06-10
    • 1970-01-01
    相关资源
    最近更新 更多