【问题标题】:Creating a function from a member of an instance for another instance in python从一个实例的成员为python中的另一个实例创建一个函数
【发布时间】:2011-09-14 18:21:34
【问题描述】:

假设我有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()

【问题讨论】:

  • 如果您选择更具描述性的变量名称,您的示例将不会那么混乱。 F THE BE THE C THE FF THE A 伤害了我的眼睛。 (我只是说!)
  • 本应维护这一点的人——当然——讨厌你让ff 变得如此复杂,而c.b() 本来会如此简单和清晰。这样做的原因是什么?
  • @S.Lott 这样做的原因是复制具有存储在属性中的彼此功能的对象网络。我意识到,从长远来看,我必须找到一种不那么令人困惑的方法,但现在这似乎是更合乎逻辑的方法。
  • @jathanism 抱歉,下次我至少会使用官方占位符名称作为鸡蛋和垃圾邮件。
  • @ChAoS:与其浪费时间,不如实际发布您的实际问题:“如何将方法名称存储为属性”或“如何“复制”(克隆、深拷贝、浅复制)对象网络。”或实际适用于您的实际问题的东西。例如,a.the_method= a.b 在“复制”这个结构时可能比f=a.b 聪明得多。

标签: python class function copy member


【解决方案1】:

你可以为类使用方法引用而不是实例引用吗?

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

a = A()
c = A()

func = A.whoami

func(a)
func(c)

【讨论】:

  • 谢谢!从长远来看,这似乎是要走的路!
【解决方案2】:

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

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

__func__ 属性实际上是 the same 作为 Ned Batchelders im_func,但 __func__ 与 python 3 前向兼容。

在一种情况下这不起作用:内置类的方法。 __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 方法并传入第一个参数 (@ 987654340@) 手动,如 Cixates 回答。但是谁知道呢,也许有一天,在一些奇怪的情况下,这可能对你们中的一些人有用。 ;)

【讨论】:

  • 对所提问题的非常完整的回答!
【解决方案3】:

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

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

【讨论】:

  • 我希望我可以将多个答案标记为所选答案! +1 快速回答。
猜你喜欢
  • 2020-10-23
  • 2020-02-13
  • 1970-01-01
  • 1970-01-01
  • 2016-06-24
  • 2016-08-25
  • 1970-01-01
  • 2018-11-02
  • 1970-01-01
相关资源
最近更新 更多