代码之家  ›  专栏  ›  技术社区  ›  Ponkadoodle

复制实例中的函数

  •  2
  • Ponkadoodle  · 技术社区  · 15 年前

    下面是一些(简化的)代码,用于我要做的事情:

    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()时成为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 = ""
    
    2 回复  |  直到 15 年前
        1
  •  2
  •   Brian McKenna    15 年前

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

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

    当然,你可以用 __class__ 如果您不知道instofb的类型:

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

    如果 instOfA 不需要存储方法,只需传入 a 作为 self :

    instOfB.printSelf.__func__(instOfA)
    
        2
  •  0
  •   Daniel G    15 年前

    问题是 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)
    

    这样看起来有点难看,但比布赖恩的解决方案(也很好用)更干净更明显。

    编辑:

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

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

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