Here's some (simplified) code for what I'm trying to do:
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>
When I call instOfA.printSelf(), it prints self as being instOfB.
But I want self to be instOfA when I call instOfA.printSelf(), and instOfB when I call instOfB.printSelf() How would I go about doing this without manually defining printSelf in class a? To those wondering why I would even want to do something like this, here's a longer example:#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'
I realize it's a bit unusual, but 开发者_如何转开发I couldn't think of a different way of doing it. I'm effectively trying to subclass an instance. It'd look something like this if Python allowed it:
class aInstance(aDef):
inputStr = ""
You can use the descriptor of the method to get a bound method:
instOfA.printSelf = b.printSelf.__get__(instOfA)
Of course, you can use __class__
if you don't know the type of instOfB:
instOfA.printSelf = instOfB.__class__.printSelf.__get__(instOfA)
If instOfA
doesn't need the method stored, you can just pass in an instance of a
as self
:
instOfB.printSelf.__func__(instOfA)
The issue is that instOfB.printSelf
is a bound method - the self
variable is set to be instOfB when you create the object. What I would do, frankly, is just to set up the function slightly differently:
class b:
def printSelf(self, other):
print other
Then you simply do
instOfA = a()
instOfB = b()
instOfA.printSelf = instOfB.printSelf
instOfA.printSelf(instOfA)
And if you want to do that with instOfB:
instOfB.printSelf(instOfB)
It's slightly uglier that way, but it's a bit cleaner and more obvious than Brian's solution (which works just fine as well).
Edit:
An even better way is to use descriptors (although this still requires modifying your code):
class b:
@staticmethod
def printSelf(self):
print self
Though you still have to include the instance of the object when calling the function.
精彩评论