Python:用属性重写成员?

Python:用属性重写成员?,python,inheritance,properties,Python,Inheritance,Properties,我试图用属性覆盖Python(2.7)类的一个成员,如下代码所示: class Base: def __init__(self): self.foo = 1 class Derived(Base): foo = property(lambda self: 2) print Derived().foo 但是,最后一行打印的是1,而不是2。从我认为属性应该起作用的方式(即,以后很容易将成员更改为函数)来看,这似乎与我的直觉背道而驰。我错过什么了吗?有一些解决方法

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

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

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

print Derived().foo

但是,最后一行打印的是1,而不是2。从我认为属性应该起作用的方式(即,以后很容易将成员更改为函数)来看,这似乎与我的直觉背道而驰。我错过什么了吗?有一些解决方法吗?

这不起作用,因为您没有使用新样式的类。属性是
描述符
,仅适用于新样式的类。您的代码所做的是:

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

如果您更改:

class Base: #old style class
致:


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

这不起作用,因为您没有使用新样式的类。属性是
描述符
,仅适用于新样式的类。您的代码所做的是:

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

如果您更改:

class Base: #old style class
致:


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

,在该问题得到解决之后,它将无法工作,因为它将直接覆盖父级的
foo
成员,因此您将永远无法设置
foo
。并且无法使用新样式的类…?=)您的类将从对象派生。类基(对象):@sr2222这不是真的-的第一个参数是getter。这将在一个新样式的类上生成一个非常好的只读属性。不知怎的,我脑子里的参数顺序倒过来了…@Lattyware——但是
self.foo
是在
Base中设置的。\uuu init\uuu
将尝试使用该属性。解决该问题后,它将不起作用,因为它将直接覆盖父级的
foo
成员,因此,您将永远无法设置
foo
。并且无法使用新样式的类…?=)您的类将从对象派生。类基(对象):@sr2222这不是真的-的第一个参数是getter。这将在一个新样式的类上生成一个非常好的只读属性。不知怎的,我脑子里的参数顺序倒过来了…@Lattyware——但是
self.foo
是在
Base中设置的。\uuuu init\uuu
将尝试使用该属性。我确信这只是一个示例,但使用的是
property()
作为实际的
def
上的装饰器要比直接使用
lambda
可读性强得多。故事的寓意:始终使用新样式的类。@Lattyware:实际上,我个人更喜欢简单属性中的
lambda
样式:)@rainer好吧,简单的属性不应该存在(正如我所说,我认为这只是一个例子)。任何复杂到值得使用一个属性的事情都最好像我上面解释的那样,为了可读性。我确信这只是一个例子,但是使用
property()
作为实际的
def
上的装饰器要比直接使用
lambda
可读性强得多。故事的寓意:始终使用新样式的类。@Lattyware:实际上,我个人更喜欢简单属性中的
lambda
样式:)@rainer好吧,简单的属性不应该存在(正如我所说,我认为这只是一个例子)。为了可读性,任何足够复杂、值得使用的属性都最好像我上面解释的那样完成。