Python:用属性重写成员?
我试图用属性覆盖Python(2.7)类的一个成员,如下代码所示: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。从我认为属性应该起作用的方式(即,以后很容易将成员更改为函数)来看,这似乎与我的直觉背道而驰。我错过什么了吗?有一些解决方法
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好吧,简单的属性不应该存在(正如我所说,我认为这只是一个例子)。为了可读性,任何足够复杂、值得使用的属性都最好像我上面解释的那样完成。