我需要在运行时为一个方法生成代码。能够运行任意代码并拥有文档字符串是很重要的。
我想出了一个结合了exec和setattr的解决方案,下面是一个虚拟示例:
class Viking(object):
def __init__(self):
code = '''
def dynamo(self, arg):
""" dynamo's a dynamic method!
"""
self.weight += 1
return arg * self.weight
'''
self.weight = 50
d = {}
exec code.strip() in d
setattr(self.__class__, 'dynamo', d['dynamo'])
if __name__ == "__main__":
v = Viking()
print v.dynamo(10)
print v.dynamo(10)
print v.dynamo.__doc__有没有更好/更安全/更地道的方法来达到同样的结果?
发布于 2009-02-10 18:38:48
函数文档字符串和名称都是可变属性。您可以在内部函数中做任何您想做的事情,甚至可以有多个版本的内部函数,供makedynamo()在其中进行选择。不需要使用字符串构建任何代码。
下面是解释器中的一段代码:
>>> def makedynamo(i):
... def innerdynamo():
... print "in dynamo %d" % i
... innerdynamo.__doc__ = "docstring for dynamo%d" % i
... innerdynamo.__name__ = "dynamo%d" % i
... return innerdynamo
>>> dynamo10 = makedynamo(10)
>>> help(dynamo10)
Help on function dynamo10 in module __main__:
dynamo10()
docstring for dynamo10发布于 2009-02-10 18:38:44
Python将允许您在函数中声明函数,因此您不必使用exec技巧。
def __init__(self):
def dynamo(self, arg):
""" dynamo's a dynamic method!
"""
self.weight += 1
return arg * self.weight
self.weight = 50
setattr(self.__class__, 'dynamo', dynamo)如果您想要该函数的多个版本,您可以将所有这些放入一个循环中,并在setattr函数中更改它们的名称:
def __init__(self):
for i in range(0,10):
def dynamo(self, arg, i=i):
""" dynamo's a dynamic method!
"""
self.weight += i
return arg * self.weight
setattr(self.__class__, 'dynamo_'+i, dynamo)
self.weight = 50(我知道这不是很好的代码,但它让人明白了这一点)。至于设置文档字符串,我知道这是可能的,但我必须在文档中查找它。
编辑:您可以通过dynamo.__doc__设置文档字符串,因此您可以在循环体中执行以下操作:
dynamo.__doc__ = "Adds %s to the weight" % i另一个编辑:在@eliben和@bobince的帮助下,闭包问题应该得到解决。
发布于 2018-02-17 05:48:11
class Dynamo(object):
def __init__(self):
pass
@staticmethod
def init(initData=None):
if initData is not None:
dynamo= Dynamo()
for name, value in initData.items():
code = '''
def %s(self, *args, **kwargs):
%s
''' % (name, value)
result = {}
exec code.strip() in result
setattr(dynamo.__class__, name, result[name])
return dynamo
return None
service = Dynamo.init({'fnc1':'pass'})
service.fnc1()https://stackoverflow.com/questions/533382
复制相似问题