将方法应用于另一个类的对象

geo*_*org 5 python

给定两个不相关的类A和B,如何A.method使用B的对象调用self

class A:
    def __init__(self, x):
        self.x = x

    def print_x(self):
        print self.x

class B:
    def __init__(self, x):
        self.x = x

a = A('spam')
b = B('eggs')

a.print_x() #<-- spam
<magic>(A.print_x, b) #<-- 'eggs'
Run Code Online (Sandbox Code Playgroud)

Rei*_*ica 9

在Python 3.x中,您可以简单地执行您想要的操作:

A.print_x(b) #<-- 'eggs'
Run Code Online (Sandbox Code Playgroud)

如果您只有一个'A'实例,那么先获取该类:

a.__class__.print_x(b) #<-- 'eggs'
Run Code Online (Sandbox Code Playgroud)

在Python 2.x(OP使用的)中,这不起作用,如OP所述并在评论中由Amber解释:

这是Python 2.x和Python 3.x之间的区别 - 3.x中的方法不强制传递相同的类.

更多细节(OP编辑)

在python 2中,A.print_x返回一个"未绑定的方法",它不能直接应用于其他类的对象:

当调用未绑定的用户定义方法对象时,将调用基础函数(im_func),并限制第一个参数必须是正确类(im_class)或其派生类的实例.>> http://docs.python.org/reference/datamodel.html

要解决这个限制,我们首先必须从方法中获取"原始"函数,通过im_func__func__(2.6+),然后可以将其称为传递对象.这适用于类和实例:

# python 2.5-
A.print_x.im_func(b)    
a.print_x.im_func(b)

# python 2.6+
A.print_x.__func__(b)   
a.print_x.__func__(b)
Run Code Online (Sandbox Code Playgroud)

在python 3中,没有这样的东西作为未绑定的方法.

未绑定的方法已经不复存在了.ClassObject.method返回一个普通的函数对象,instance.method仍然返回一个绑定的方法对象.>> http://www.python.org/getit/releases/3.0/NEWS.txt

因此,在python 3中,A.print_x它只是一个函数,可以立即调用,a.print_x但仍然必须是无界的:

# python 3.0+
A.print_x(b)
a.print_x.__func__(b)
Run Code Online (Sandbox Code Playgroud)