Pergunta

Aqui está algum código (simplificado) para o que estou tentando fazer:

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>

Quando eu chamo instofa.printself (), ele imprime como sendo instofb.
Mas eu quero que eu seja Instofa quando ligo para instofa.printself () e instofb quando eu chamo instofb.printself ()
Como eu faria isso sem definir manualmente a impressão na classe A?

Para aqueles que se perguntam por que eu gostaria de fazer algo assim, aqui está um exemplo mais longo:

#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'

Sei que é um pouco incomum, mas não conseguia pensar em uma maneira diferente de fazê -lo. Estou efetivamente tentando subclasse uma instância. Pareceria algo assim se Python permitisse:

class aInstance(aDef):
    inputStr = ""
Foi útil?

Solução

Você pode usar o descritor do método para obter um método vinculado:

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

Claro, você pode usar __class__ Se você não conhece o tipo de instofb:

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

Se instOfA Não precisa do método armazenado, você pode simplesmente passar em um exemplo de a Como self:

instOfB.printSelf.__func__(instOfA)

Outras dicas

A questão é que instOfB.printSelf é um Método ligado - a self A variável está definida para ser instofb quando você cria o objeto. O que eu faria, francamente, é apenas configurar a função um pouco diferente:

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

Então você simplesmente faz

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

E se você quiser fazer isso com o Instofb:

instOfB.printSelf(instOfB)

É um pouco mais feio dessa maneira, mas é um pouco mais limpo e mais óbvio que a solução de Brian (o que funciona muito bem).

Editar:

Uma maneira ainda melhor é usar descritores (embora isso ainda exija modificar seu código):

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

Embora você ainda precise incluir a instância do objeto ao chamar a função.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top