10

我有一个对象定义如下

class a():
    @property
    def prop(self):
        print("hello from object.prop")
        @property
        def prop1(self):
            print("Hello from object.prop.prop")

当我打电话

>>> obj = a()
>>> obj.prop
hello from object.prop
>>> obj.prop.prop

我收到以下回溯错误

Traceback (most recent call last):
  File "object_property.py", line 13, in <module>
    a.prop.prop1
AttributeError: 'NoneType' object has no attribute 'prop1'

我想弄清楚是否可以为对象定义嵌套属性?

4

2 回答 2

11

回溯是因为您的属性没有return声明,因此它返回NoneType,它显然不能拥有自己的属性。您的属性可能需要返回具有自己prop属性的不同类的实例。像这样的东西:

class a():
    def __init__(self):
        self.b = b()
    @property
    def prop(self):
        print("hello from object.prop")
        return self.b

class b():
    @property
    def prop(self):
        print("Hello from object.prop.prop")

x = a()
print x.prop.prop
>> hello from object.prop
>> Hello from object.prop.prop
>> None
于 2013-07-29T01:34:29.087 回答
4

一般来说,不,除了你自己之外,没有办法包装对象的属性访问。当然,没有什么语法可以整齐地嵌套(您可以在属性函数中声明一个类,但它会很快变得丑陋)。

也就是说,在类似 的表达式中obj.prop_a.prop_b,顶级对象obj无法直接控制prop_b属性访问发生的情况,而这发生在不同的对象上。

例如,考虑以下语句序列:

foo = obj.prop_a
bar = foo.prop_b

分配给的值bar与 相同obj.prop_a.prop_b,但该语句根本没有直接引用obj

如果您愿意进入 wrapper 对象的阴暗世界,也许可以做您想做的事,但它不会像基本属性那样整洁。就像在@qwwqwwq 的答案中一样,您可以obj.prop_a返回一个具有自己@property装饰函数的类的实例prop_b

prop_a如果您不担心可以从外部访问它,您甚至可以在函数内部声明该类。不过,对于任何复杂的事情,它都会很快变得一团糟。

相反,请考虑是否可以通过obj.prop_a.prop_b直接在 上的属性或方法更好地公开您想要访问的内容obj,例如obj.prop_a_b. 我怀疑您会通过这种方式找到更好的设计。

于 2013-07-29T03:21:18.237 回答