In Python, can you call an instance method of class A, but pass in an instance of class B?

前端 未结 4 1755
轻奢々
轻奢々 2020-12-19 07:57

In the interest of reusing some existing code that was defined as an instance method of a different class, I was tying to do something like the following:

cl         


        
相关标签:
4条回答
  • 2020-12-19 08:35

    It happens because python wraps class functions as an "unbound method" which performs this type checking. There's some description of the decisions involved in this here.

    Note that this type checking has actually been dropped in python 3 (see the note at the end of that article), so your approach will work there.

    0 讨论(0)
  • 2020-12-19 08:38

    Looks like this works:

    Foo.hello.im_func(bar)
    

    Hello, I am Bar.

    I guess I need to read a this little harder...

    0 讨论(0)
  • 2020-12-19 08:38

    This is an old question, but Python has evolved and looks like it's worth pointing it out:

    with Python 3 there's no more <unbound method C.x>, since an unbound method is simply a <function __main__.C.x>!

    Which probably means the code in the original question should not be considered /that/ off. Python has always been about duck typing in any case, hasn't it?!

    Refs:

    • Guido proposing to remove unbound methods from python
    • What's new for Python 3 release
    • Get defining class of unbound method object in Python 3

    Alternative solution in Py2

    Note that there's also an alternative solution to the "explorative" question (see 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
    

    Ref:

    Some ipython code samples

    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>
    
    0 讨论(0)
  • 2020-12-19 08:58

    A while back I wondered about the same "feature" in Perl on PerlMonks, and the general consensus was that while it works (as it does in Python) you should not be doing things that way.

    0 讨论(0)
提交回复
热议问题