2010-01-25 2 views
2

Вот некоторые (упрощенный) код для того, что я пытаюсь сделать:функции копирования, расположенные в тех случаях,

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(), он выводит себя как instOfB.
Но я хочу, чтобы я был instOfA, когда я вызываю instOfA.printSelf() и instOfB, когда я вызываю instOfB.printSelf()
Как мне это сделать без ручного определения printSelf в классе a?

Для тех, кому интересно, почему я даже хочу сделать что-то вроде этого, вот уже пример:

#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 = "" 
+0

Вам не нужно [python] в заголовке, просто пометьте его python. – richo

+0

Поставив [python] в их, я пытался сказать, что это что-то конкретное, как сделать что-то в Python, а не сказать, алгоритм, который может быть реализован на любом языке, но я решил сделать это на Python. – Ponkadoodle

+0

Это именно то, что люди ожидают от знака python. :-) –

ответ

2

Вы можете использовать дескриптор метода, чтобы получить связанный метод:

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

Конечно, вы можете использовать __class__, если вы не «т знать тип instOfB:

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

Если instOfA не нужен метод хранимого, вы можете просто передать в экземпляре a в self:

instOfB.printSelf.__func__(instOfA) 
0

Вопрос заключается в том, что 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) 

Это немного уродливее, но это немного чище и более очевидно, чем решение Брайана (что тоже прекрасно работает).

Edit:

Еще лучший способ заключается в использовании дескрипторов (хотя это по-прежнему требует изменения кода):

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

Хотя вы все еще должны включать в себя экземпляр объекта при вызове функция.

+1

Это гораздо лучшее решение. Я бы переименовал 'object', хотя это довольно важно в Python (даже если это не имеет значения в этом примере). –

+0

Несмотря на то, что это хорошее, чистое решение, оно требует, чтобы я менял все свои функции. Решение Брайана позволяет мне обойти это. – Ponkadoodle

+0

@Brian - упс, конечно! –

Смежные вопросы