代码之家  ›  专栏  ›  技术社区  ›  Jason DeFontes

在Python中,可以调用类A的实例方法,但传入类B的实例吗?

  •  6
  • Jason DeFontes  · 技术社区  · 16 年前

    为了重用一些定义为不同类的实例方法的现有代码,我打算执行如下操作:

    class Foo(object):
      def __init__(self):
        self.name = "Foo"
    
      def hello(self):
        print "Hello, I am " + self.name + "."
    
    class Bar(object):
      def __init__(self):
        self.name = "Bar"
    
    
    bar = Bar()
    Foo.hello(bar)
    

    但结果是:

    类型错误:必须使用foo instance作为第一个参数调用未绑定的方法hello()(改为获取bar实例)

    这样的事情有可能吗?


    我应该清楚我知道这是个坏主意。显然,真正的解决方案是重构。我只是想一定有办法,结果证明是有办法的。

    谢谢你的评论。

    4 回复  |  直到 9 年前
        1
  •  9
  •   Jason DeFontes    16 年前

    看起来这是可行的:

    Foo.hello.im_func(bar)
    

    你好,我是酒吧。

    我想我需要读一本 this 再难一点…

        2
  •  5
  •   Brian    16 年前

    发生这种情况是因为python将类函数包装为执行此类型检查的“未绑定方法”。关于这件事的决定有一些描述 here .

    请注意,这种类型检查实际上已经在python 3中被删除(请参见本文末尾的注释),因此您的方法可以在这里工作。

        3
  •  2
  •   Community CDub    8 年前

    这是一个古老的问题,但是python已经进化了,看起来值得指出:

    有了python 3,就没有了 <unbound method C.x> ,因为未绑定的方法只是 <function __main__.C.x> !

    这可能意味着不应该考虑原始问题中的代码。不管怎样,python一直都是关于鸭子打字的,不是吗?!

    参考文献:

    PY2中的替代溶液

    请注意,“探索性”问题也有另一种解决方案(请参见 Python: Bind an Unbound Method? ):

    In [6]: a = A.a.im_func.__get__(B(), B)
    
    In [7]: a
    Out[7]: <bound method B.a of <__main__.B instance at 0x7f37d81a1ea8>>
    
    In [8]: a(2)
    2
    

    裁判:

    一些ipython代码示例

    Python 2

    In [1]: class A():
        def a(self, a=0):
            print a
       ...:
    
    In [2]: A.a
    Out[2]: <unbound method A.a>
    
    In [3]: A.a.im_func
    Out[3]: <function __main__.a>
    
    In [4]: A.a(B())
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-4-7694121f3429> in <module>()
    ----> 1 A.a(B())
    
    TypeError: unbound method a() must be called with A instance as first argument (got B instance instead)
    

    Python 3

    In [2]: class A():
        def a(self, a=0):
            print(a)
       ...:
    
    In [3]: def a():
       ...:     pass
       ...:
    
    In [4]: class B():
       ...:     pass
    
    In [5]: A.a(B())
    0
    
    In [6]: A.a
    Out[6]: <function __main__.A.a>
    
        4
  •  0
  •   Thilo    16 年前

    不久前,我想知道Perl中关于Perlmonks的相同“特性”,以及 general consensus 当它工作时(就像在Python中一样),您不应该这样做。