在python中从实例的成员为另一个实例创建函数

2024-04-29 11:24:50 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有f,它是类实例成员的函数:

class A:
    def b(self):
        print 'hey'

a = A()
f = a.b

如果我有同一个类的另一个实例,比如说c = A(),那么我如何只使用fc来重建一个新的ff,所以调用ff()会导致c.b()而不是a.b()?你知道吗

c = A()
ff = some_python_kungfu(f,c)
ff() #it is calling c.b()

Tags: 实例函数selfisdefit成员some
3条回答

你能为类使用方法引用而不是实例引用吗?你知道吗

class A:
    def whoami(self):
        print 'I am %s' % id(self)

a = A()
c = A()

func = A.whoami

func(a)
func(c)

我不确定这是否适用于所有情况,但是:

def some_python_kungfu(meth, obj):
    """Get a bound method on `obj` corresponding to the method `meth`."""
    return getattr(obj, meth.im_func.__name__)

所以您想知道如何将已经绑定的方法重新绑定到另一个实例,只使用绑定方法和另一个实例。可以这样做:

def some_python_kungfu(meth, obj):
    return type(meth)(meth.__func__, obj, obj.__class__)

__func__属性实际上是the same作为im_func,但是__func__与python3是向前兼容的。你知道吗

有一种情况是这样做行不通的:内置类的方法。__func__im_func属性仅在用户定义的类上可用。因此,这将失败:

a = "that's no ordinary rabbit"
b = "consult the book of armaments"
b_split = some_python_kungfu(a.split, b)

对Ned的解决方案稍加修改应用于内置类和用户定义类:

def some_python_kungfu(meth, obj):
    return getattr(obj, meth.__name__)

那么这会一直有效吗?好。。。不,但绊脚石是一个相当模糊且(我猜)很少出现的问题:如果方法的名称(meth.__name__)与它在类字典('b')中的名称不同,那么getattr将返回错误的属性或引发AttributeError。例如:

def external(self):
   pass
class A(object):
   b = external

这里A.b.__name__ == 'external'而不是'b',因此将调用getattr(obj, 'external')而不是getattr(obj, 'b')。你知道吗

虽然前面的两种方法都有问题,一种是内置类,另一种是拼凑类,但这两种问题在任何情况下都不会同时出现。因此,组合在所有情况下都有效:

def some_python_kungfu(meth, obj):
    try:
        return type(meth)(meth.__func__, obj, obj.__class__)
    except AttributeError:
        # meth is a built-in method, so meth.__name__ is always correct
        return getattr(obj, meth.__name__)

如本页其他地方所述,最好的办法可能是忽略整个混乱,以更干净的方式进行操作,例如使用unbound方法并手动传入第一个参数(self),如Cixates answer。但谁知道呢,也许有一天,在一些奇怪的情况下,这对你们中的一些人来说是有用的。;)

相关问题 更多 >