目标:
在执行__init__
变量(对象创建)后动态生成方法。
首先(不是动态的例子):
string_custom_method='''def custom_method(self):
print self.text'''
class Foo:
def __init__(self):
self.text='foo'
exec string_custom_method
Foo().custom_method()
这个脚本非常简单,效果很好。问题是我实际上需要自定义string_custom_method
:
string_custom_method='''def custom_method(self):\n'''
def create_custom_method(print_end):
global string_custom_method
string_custom_method+='\t'+'print self.text\n'
if print_end:
string_custom_method+='\t'+'print "end"'
class Faa:
def __init__(self):
self.text='faa'
create_custom_method(True)
exec string_custom_method
Faa().custom_method()
问题是我收到以下错误:
def custom_method(self):
^
SyntaxError: unexpected EOF while parsing
所以我的结论是python在执行__init__
之前读取方法树,这在这种情况下有点问题。
在阅读了更多有关此内容之后,我想也许可以使用staticmethod
这样:self.custom_method = staticmethod(...)
可行,
但问题是custom_method
它没有在全局范围内定义,在__init__
执行之前我无法定义它。
有没有办法让这项工作?我知道,对于这个例子,它看起来似乎没用,但我真的需要它用于我的程序!
答案 0 :(得分:1)
如果这样做的动机是您已经执行了数十亿次循环,我强烈推荐numba jit。
答案 1 :(得分:1)
预编译代码的工作解决方案:
funtpl = """
def __TheFunction__(self):
%s
"""
def create_custom_method(print_end):
# this would be better done by a template engine I think
source = ['print self.text']
if print_end:
source.append('print "end"')
source = funtpl % "\n ".join(source)
bytecode = compile(source, "<string>", "exec", )
locals = {}
eval(bytecode, globals(), locals)
return locals["__TheFunction__"]
class Faa(object):
def __init__(self, print_end):
self.text='faa'
fun = create_custom_method(print_end)
self.custom_method = fun.__get__(self, type(self))
f = Faa(True)
f.custom_method()
通过步调试器运行f.custom_method
祝你好运
答案 2 :(得分:-1)
__init__()
行执行后调用 exec string_custom_method
。首先构造类,该行在类范围内,因此它在构造类本身时执行,然后python使用类创建实例,此时调用__init__()
。