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.
You can also use MethodType from types module.
import types
def hello1(self):
print(self.name,"says hi")
def hello2(self):
print(self.name,"says hello")
class A:
def __init__(self, name, opt=0):
self.name = name
if opt == 1:
self.hello = types.MethodType(hello1, self)
else:
self.hello = types.MethodType(hello2, self)
A('a').hello() # ('a', 'says hello')
A('a', 1).hello() # ('a', 'says hi')
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.