0

I've defined a class like this:

class MyClass:
  def GetValue(self):
    return 5
  def PrintValue(self):
    print self.GetValue()

For some instances of MyClass I need to re-define the GetValue() dinamically, i.e. something like this:

def GetAGoodValue(self):
  return 7

oneObject=MyClass()
oneObject.GetValue=GetAGoodValue
oneObject.PrintValue()

After re-defining I get the errror:

TypeError: not enough arguments; expected 1, got 0

If inside the PrintValue method I code instead:

print self.GetValue(self)

then the above code works, but only for those MyClass instances where the GetValue method is re-defined. Instances where the GetValue method is not re-defined yeld the error:

TypeError: too many arguments; expected 1, got 2

Any suggestion?

user1737538
  • 497
  • 2
  • 7
  • 16
  • 1
    It's more a duplicate of the older http://stackoverflow.com/questions/972/adding-a-method-to-an-existing-object , which has a nicer answer as well. –  Jun 03 '14 at 10:02
  • Exactly. The originally linked question is about changing methods of a class, not of an object, which is a slightly different topic. – glglgl Jun 03 '14 at 10:03
  • @Evert Must be one of the first ones here... #972, wow... – glglgl Jun 03 '14 at 10:04

1 Answers1

1

If you assign a method to a single object instead of changing the whole class, you have to implement the ususally-done binding yourself.

So you have two options:

Either you do

oneObject.GetValue = lambda: GetAGoodValue(oneObject)

or you "ask" the function object what it would do if called as a class attribute:

oneObject.GetValue = GetAGoodValue.__get__(oneObject, MyClass)

so that it works as intended.

glglgl
  • 89,107
  • 13
  • 149
  • 217
  • Sorry for being back so late, not enough time! Thank you for your answer. Your first suggestion works. The second gives me the following error: `AttributeError: __get__` Maybe it's because I'm working with a very old version of Python (1.5.2): unfortunately I have to! – user1737538 Jun 11 '14 at 15:22
  • @user1737538 Yes, the descriptor protocol (the thing with `__get__`) is newer than 1.5.2... – glglgl Jun 11 '14 at 15:57
  • One more question: I'm trying to use your suggestion to implement another "function substitution". This time the function has some parameters, something like `GetScaledValue(self,min,max)`. What I'm trying to do is to assign `oneObject.GetScaledValue=lambda: GetAGoodScaledValue(oneObject,min,max)' but I get the error 'TypeError: no arguments expected' when I call `self.GetScaledValue(10,100)` from inside the class. Sorry, but I'm very new to this language (used to .NET). – user1737538 Jun 11 '14 at 16:07
  • 1
    I got it: it must be `oneObject.GetScaledValue=lambda min,max: GetAGoodScaledValue(oneObject,min,max)`. – user1737538 Jun 11 '14 at 16:10