【问题标题】:Self-modifying Python class自修改 Python 类
【发布时间】:2014-09-21 01:18:22
【问题描述】:

我想在运行时修改一个类的初始化器。像这样的代码有什么潜在的问题吗?我是装饰器的新手,所以不太确定。

class Object:
    def __init__(self):
        print "do something"
    @classmethod
    def modify(cls, f):
        __init___old = cls.__init__
        def __init__(self):
            __init___old(self)
            f(self)
        cls.__init__ = __init__
        return f

@Object.modify
def f(self):
    print "do something else"

【问题讨论】:

  • 这毫无意义。为什么这被实现为装饰器?你到底想做什么(在更广泛的背景下)?
  • 我想在类级别而不是实例级别实现 register-handler-with-decorator 模型。另外,在我的实际代码中,函数被包装了,我只是想对我不确定的代码元素提出问题。

标签: python class metaprogramming decorator


【解决方案1】:

除了让不习惯 python 强大的元编程工具的人感到困惑之外,像你这样的事情应该可以正常工作。类可修改是python的一个特性。

但是,我建议找到一种更传统的方式来做你需要做的事情,元编程会导致文件中的源代码不再与粗略检查代码所暗示的代码相匹配,所以它是可读性不是很好。对于这种特殊情况,您可以附加到类变量中的列表,以便在__init__ 的循环中调用。

您可能会或可能不会遇到的唯一问题是,如果您使用 python 优化编译器,例如psyco、pypy,使用像这样的动态特性可能会导致它们无法像其他方式那样优化事物。

【讨论】:

  • 谢谢,我没想到使用类变量,这样更干净。
【解决方案2】:

与其像这样重新定义__init__,不如让你的类保留一个应该在对象初始化时执行的函数列表(可以扩充)。

class Object:
    obj_initializers = []
    def __init__(self):
        print "do something"
        for f in self.obj_initializers:
            f(self)

    @classmethod
    def add_initializer(cls, f):
        cls.obj_initializers.append(f)

def f(self):
    print "do something else"

Object.add_initializer(f)

在您的代码中,f 实际上并未被修改;您只是在滥用装饰器语法以 f 作为参数执行另一个函数。

【讨论】:

    猜你喜欢
    • 2011-01-11
    • 2017-12-23
    • 1970-01-01
    • 2018-01-24
    • 1970-01-01
    • 2022-01-19
    • 2017-03-21
    • 1970-01-01
    • 2012-11-04
    相关资源
    最近更新 更多