【问题标题】:copying functions located in instances复制位于实例中的函数
【发布时间】:2010-01-25 02:44:16
【问题描述】:

这是我正在尝试做的一些(简化的)代码:

class a:
    pass

class b:
    def printSelf(self):
        print self


instOfA = a()
instOfB = b()
instOfA.printSelf = instOfB.printSelf
instOfA.printSelf()
  <__main__.b instance at 0x0295D238>

当我调用 instOfA.printSelf() 时,它会将 self 打印为 instOfB。
但是当我调用 instOfA.printSelf() 时我希望 self 成为 instOfA,当我调用 instOfB.printSelf() 时我希望自己成为 instOfB
如果不在 a 类中手动定义 printSelf,我该怎么做呢?

对于那些想知道为什么我什至想做这样的事情的人,这里有一个更长的例子:

#Acts as a template for aInstance. I would have several aInstances that have common rules, which are defined by an instance of the aDefinition class (though I'd have multiple rule sets too)
class aDefinitionClass: 
    def setInput(self, val):
        self.inputStr = val
    def checkInputByLength(self):
        return len(self.inputStr) < 5
    def checkInputByCase(self):
        return self.inputStr == self.inputStr.upper()
    checkInput = checkInputByLength


class aInstance(aDefinition):
    inputStr = ""
    def __init__(self, ruleDefinition):
        self.checkInput = ruleDefinition.checkInput


aDef = aDefinitionClass()
aDef.checkInput = aDef.checkInputByCase #Changing one of the rules.
aInst = aInstance(aDef)
aInst.setInput("ABC")
aInst.checkInput()
  AttributeError: aDefinitionClass instance has no attribute 'inputStr'

我意识到这有点不寻常,但我想不出另一种方法。我正在有效地尝试子类化一个实例。如果 Python 允许,它看起来像这样:

class aInstance(aDef):
    inputStr = ""

【问题讨论】:

  • 标题中不需要[python],直接标记python即可。
  • 通过将 [python] 放入其中,我想说这是特定于如何在 Python 中做某​​事的东西,而不是说可以用任何语言实现的算法,但我选择了用 Python 来做。
  • 这正是人们期望 python 标签的含义。 :-)
  • 好的,我改一下。你为什么要删除你的答案米哈尔?看看我的评论,我不敢相信我用错了“那里”,当其他人这样做时,我总是很恼火......
  • 不,我希望每个实例共享相同的规则,但有自己的变量。如果这些方法仍然绑定到 instOfB,那么在该方法内读取/更改的任何变量都将位于 instOfB 上。阅读第二个示例(连同 cmets)可能有助于澄清这一点。

标签: python function self multiple-instances


【解决方案1】:

可以使用方法的描述符来获取绑定的方法:

instOfA.printSelf = b.printSelf.__get__(instOfA)

当然,如果你不知道instOfB的类型,你可以使用__class__

instOfA.printSelf = instOfB.__class__.printSelf.__get__(instOfA)

如果instOfA 不需要存储的方法,您可以将a 的实例作为self 传递:

instOfB.printSelf.__func__(instOfA)

【讨论】:

    【解决方案2】:

    问题在于instOfB.printSelf 是一个绑定方法 - 当您创建对象时,self 变量被设置为 instOfB。坦率地说,我会做的只是稍微不同地设置函数:

    class b:
        def printSelf(self, other):
            print other
    

    那你就干吧

    instOfA = a()
    instOfB = b()
    instOfA.printSelf = instOfB.printSelf
    instOfA.printSelf(instOfA)
    

    如果你想用 instOfB 做到这一点:

    instOfB.printSelf(instOfB)
    

    这种方式稍微难看,但比 Brian 的解决方案更干净、更明显(效果也很好)。

    编辑:

    一个更好的方法是使用描述符(尽管这仍然需要修改你的代码):

    class b:
        @staticmethod
        def printSelf(self):
            print self
    

    虽然你在调用函数时仍然必须包含对象的实例。

    【讨论】:

    • 这是一个更好的解决方案。不过,我会重命名 object,它在 Python 中相当重要(即使在此示例中无关紧要)。
    • 虽然这是一个很好、干净的解决方案,但它需要我更改所有功能。 Brian 的解决方案让我能够解决这个问题。
    • 你改变了它的一部分,把你还在尝试打印对象;)
    猜你喜欢
    • 2023-02-05
    • 1970-01-01
    • 1970-01-01
    • 2018-01-03
    • 1970-01-01
    • 2023-03-04
    • 2012-03-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多