执行__init __

时间:2015-07-01 11:41:42

标签: python

目标: 在执行__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__执行之前我无法定义它。

有没有办法让这项工作?我知道,对于这个例子,它看起来似乎没用,但我真的需要它用于我的程序!

3 个答案:

答案 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__()