如果我有一个python类,它允许在实例化时使用options参数,那么如何根据该options参数的值动态设置一个函数。例如,如果我有代码
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()
我收到了追溯错误
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
答案 0 :(得分:5)
您的函数没有定义self
参数,也没有定义参数。
您需要使用方法;您可以通过将它们视为descriptors并在其上明确调用.__get__()
来从函数中创建这些函数:
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)))
通常,在类(直接或通过实例)访问函数时,会对函数调用.__get__()
方法。但是,直接在实例上添加的函数不会发生这种情况,因此您需要手动执行此操作。
答案 1 :(得分:0)
您还可以使用类型模块中的MethodType。
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')