This is related to this question however the methods described there do not work.
I have a certain class Dog
with a method woofwoof
and an attribute woof
. There is a second method bark
which returns woofwoof()
. For a given instance of Dog
, I want to redefine bark
so that it returns the value of woof
. Importantly, bark
must remain a method given downstream code relies on calling bark
.
See a minimum working example below.
class Dog:
woof = 'woof'
def woofwoof(self):
return 'woof woof'
def woOof(self):
return 'woOof'
def bark(self):
return self.woofwoof()
def test(foo):
print(type(foo.bark))
print(foo.bark())
foo = Dog()
test(foo)
foo.bark = foo.woOof
test(foo)
foo.bark = foo.woof
test(foo)
The above code yields:
<class 'method'>
woof woof
<class 'method'>
woOof
<class 'str'>
TypeError: 'str' object is not callable
However the output I want from the last 2 lines is:
<class 'method'>
woof
That is preserve the type of bark
as a method, but make it return the value of attribute woof
(in particular so that if I change the value of woof
later on, bark
returns the updated value when called).
The value of foo.bark
has to be a callable, e.g. a function or method. You can't call a string. And even if you could, the assignment would set it to the current string, it wouldn't track changes to the attribute.
Define a method that returns self.woof
, and assign that to foo.bark
.
class Dog:
woof = 'woof'
def woofwoof(self):
return 'woof woof'
def woOof(self):
return 'woOof'
def bark(self):
return self.woofwoof()
def returnWoof(self):
return self.woof
foo = Dog()
foo.bark = foo.returnWoof
test(foo)