【问题标题】:Python: Overriding a member with a property?Python:用属性覆盖成员?
【发布时间】:2013-01-06 04:24:31
【问题描述】:

我试图用属性覆盖 Python (2.7) 类的成员,如以下代码所示:

class Base:
    def __init__(self):
        self.foo = 1

class Derived(Base):
    foo = property(lambda self: 2)

print Derived().foo

但是,最后一行打印的是 1 而不是 2。从​​我认为属性应该起作用的方式来看(即,稍后轻松地将成员更改为函数),这对我来说似乎违反直觉。我错过了什么吗?有什么解决方法吗?

【问题讨论】:

  • 我确定这只是举例,但是在实际的 def 上使用 property() 作为装饰器比直接使用 lambda 更具可读性。
  • 故事的寓意:总是使用新式类。
  • @Lattyware:实际上,我个人更喜欢简单的属性中的lambda 样式:)
  • @rainer 好吧,那么简单的属性不应该存在(正如我所说,我认为这只是示例)。任何复杂到值得使用属性的东西都最好按照我上面解释的方式完成,以提高可读性。

标签: python inheritance properties


【解决方案1】:

这不起作用,因为您没有使用新样式的类。属性是descriptors,它只适用于新式类。你的代码在做什么是这样的:

您使用类属性 foo 创建了一个类 Derived。然后,当您创建类的实例时,Base.__init__ 将接管,因为 Derived 没有 __init__,并且您添加了优先于类属性的实例属性 foo

如果你改变:

class Base: #old style class

到:

class Base(object):  #new style class

您将遇到一个全新的问题,主要是您的属性没有适当定义的setter,因此当您在Base.__init__ 中执行self.foo = 1 时,您将得到一个AttributeError

【讨论】:

  • 而在这个问题解决之后,它就不起作用了,因为它会直接覆盖父级的foo 成员,所以你永远无法设置foo
  • 并使用新式类...? =) 你的类应该派生自对象。类基(对象):
  • @sr2222 这不是真的 - property() 的第一个参数是 getter。这将在新样式的类上生成一个完美的只读属性。
  • 糟糕,我的错,没错。以某种方式在我的脑海中倒退了参数顺序......
  • @Lattyware -- 但self.foo 设置在Base.__init__ 中,它将尝试使用该属性。
猜你喜欢
  • 2013-01-19
  • 1970-01-01
  • 2016-07-20
  • 2017-10-25
  • 1970-01-01
  • 2013-07-19
  • 1970-01-01
相关资源
最近更新 更多