If I have a python class which allows for an options parameter upon instantiation, how can I dynamically set a function to it, based upon the value of that options parameter. For example, if I have the code
def hello1():
print(self.name,"says hi")
def hello2():
print(self.name,"says hello")
class A:
def __init__(self, name, opt=0):
if opt == 1:
setattr(self,'hello',hello1)
else:
setattr(self,'hello',hello2)
if __name__ == "__main__":
a1 = A("my")
a2 = A("name",1)
a1.hello()
a2.hello()
I get the traceback error
Traceback (most recent call last):
File "dynamic_classes.py", line 17, in <module>
a1.hello()
File "dynamic_classes.py", line 5, in hello2
print(self.name,"says hello")
NameError: global name 'self' is not defined
Your functions do not define a self
parameter, nor will they ever get one.
You need to use methods; you can create these from the functions by treating them as descriptors and explicitly calling .__get__()
on them:
def hello1(self):
print(self.name,"says hi")
def hello2(self):
print(self.name,"says hello")
class A:
def __init__(self, name, opt=0):
if opt == 1:
setattr(self, 'hello', hello1.__get__(self, type(self))
else:
setattr(self, 'hello', hello2.__get__(self, type(self)))
Normally, the .__get__()
method is called on functions when accessing them on a class (either directly or via an instance). This doesn't happen for functions added directly on an instance however, so you need to do it manually.