Python如何在运行时创建类的方法

时间:2017-05-07 20:50:55

标签: python metaprogramming

我很好奇如何在运行时为类创建自定义方法...

我的意思是例如方法名,参数名,从数据库读取的方法体,并将此方法分配给类或实例。

我发现可以添加已编写的方法:

class A:
    def __init__(self):
        pass

def method(self):
    return True

A.method = method
a = A()
print(a.method())

但我有兴趣从头开始完全组装新方法:

name = "method"
params = ["self"] # Params in list should be a strings
body = "return True"
# To create method from pieces

是否可以使用__dict__?或者如何做到这一点?

2 个答案:

答案 0 :(得分:2)

方法是对象的另一个属性,即类。它们可以像其他属性一样添加:

<强>代码:

class A:
    def __init__(self):
        pass

    def method(self):
        return True

def another_method(self):
    return False

setattr(A, 'another_method', another_method)

测试代码:

a = A()
print(a.another_method())

<强>结果:

False

来自字符串的方法:

如果您确实需要从数据库中获取方法,请添加,例如:

method_string = """

def yet_another_method(self):
    return type(self).__name__

"""

exec(method_string)
setattr(A, 'yet_another_method', yet_another_method)

a = A()
print(a.yet_another_method())

<强>结果:

A

答案 1 :(得分:2)

必须谨慎对待此答案,使用execeval可以运行仲裁代码并可能危及您的系统。因此,如果您依靠用户输入来创建功能,则不得使用此 !!!

除了警告之外,你可以使用exec创建任何内容:

exec("""
def method():
    return True
""")

>>> method()
True

所以你基本上只需要一种方法来满足你的需求:

functionname = 'funfunc'
parameters = ['a', 'b']
body = 'return a + b'

exec("""
def {functionname}({parameters}):
{body}
""".format(
    functionname=functionname,
    parameters=', '.join(parameters),
    body='\n'.join(['    {line}'.format(line=line) for line in body.split('\n')])))

正文将缩进,以便有效语法,参数列表将joined使用,。测试:

>>> funfunc(1, 2)
3