1

我正在编写一个修改类的函数。目前我正在这样做(从我的单元测试中复制):

class ChildClass:
    def __init__(self):
        self.foo = 123

class Subject:
    def __init__(self):
        self.child = ChildClass()

# This is the function I'm talking about. It modifies the class "Subject".
defer_property(Subject, "child", "foo")

assertEqual(123, Subject().foo)

由于该函数修改了类,我更愿意在类定义中运行它,如下所示:

class Subject:
    defer_property("child", "foo")

    def __init__(self):
        self.child = ChildClass()

如果函数可以从上下文中获取对类的引用,那就太好了:

def defer_property(member, property_name):
    cls = get_class_reference_somehow()   # I want this magic function

    prop = property(
        # ...
    )

    setattr(cls, property_name, prop)

这可能吗?

达到类似目的的任何替代方法都会很棒。不过,我真的不想涉及元类。

4

3 回答 3

4

达到类似目标的任何替代方式都很棒。

装饰师:

def defer_property(member, property_name):
    def _(cls):
        pass # do stuff here
        return cls
    return _

用法:

@defer_property("child", "foo")
class Subject:
    pass
于 2015-10-02T14:56:28.103 回答
3

在评估主体之前,该类不存在,所以不存在。班级声明

class MyClass(object):
    foo = 3
    def __init__(self):
        pass

大致相当于

body['foo'] = 3
def init(self):
    pass
body['__init__'] = init
# *Now* create the class object
MyClass = type('MyClass', (object,), body)
于 2015-10-02T14:56:35.103 回答
1

您的函数不必自行设置属性,它可以返回它:

def defer_property(member, property_name):
    prop = property(
        # ...
    )
    return prop

class Subject:
    foo = defer_property("child", "foo")
于 2015-10-02T15:15:17.473 回答