你所看到的行为正是你应该期待的。当你定义一个类
>>> class Foo(object): pass
...
可以修改是类 - 而不是它的实例,类本身 - 因为类是另一个对象,存储在变量foo中。所以,举例来说,你可以获取和设置类的属性:
>>> Foo.a = 1
>>> Foo.a
1
换句话说,在class
关键字创建一个新类型的对象和绑定指定名称到该对象。现在
,如果你定义一个类里面另一个类(这是做的,顺便说一个奇怪的事情),即相当于定义的类体中的局部变量。而且你知道在一个类的内部定义局部变量是什么:它将它们设置为类属性。换句话说,本地定义的变量存储在类对象中,而不是存储在单个实例中。因此,
>>> class Foo(object):
... class Bar(object): pass
...
定义了一类Foo
与一种类属性,Bar
,这恰好本身是一类。尽管如此,这里没有任何子类化 - 类别Foo
和Bar
是完全独立的。(你已经实现可复制的行为如下:
>>> class Foo(object):
... class Bar(object): pass
...
>>> class Foo(object): pass
...
>>> class Bar(object): pass
...
>>> Foo.Bar = Bar
。)
所以你总是修改同一个变量!当然,你会改变你看到的价值;你已经改变了他们自己!
你的问题似乎是你在实例和类属性之间有些混淆,它们根本不是一回事。
A 类属性是一个定义在整个类别上的变量。也就是说,该类的任何实例都将共享相同的变量。例如,大多数方法都是类属性,因为您希望在每个实例(通常)上调用相同的方法。您还可以使用类属性来处理全局计数器(您已实例化此类的次数?)以及应该在实例之间共享的其他属性。
一个实例属性是一个类的实例特有的变量。也就是说,每个实例都有一个不同的变量副本,可能有不同的内容。这是您将数据存储在类中的位置 - 如果您有Page
类,那么您希望contents
属性按每个实例存储,因为不同的Page
s当然需要不同的contents
。
在你的例子中,你想要Child1.Subcls.a
和Child2.Subcls.a
为不同的变量。自然,那么,他们应该依赖于实例!
这可能有点信仰的飞跃,但是你想在Python中实现Java风格的接口?换句话说,你是否试图指定类所具有的属性和方法,而不实际定义这些属性?
这被认为是非pythonic的事情,因为普遍的共识是你应该允许类做任何他们想做的事,并且捕获当它们没有定义需要的属性时产生的异常或方法。然而,最近人们已经意识到接口实际上有时是一件好事,并且新的功能被添加到Python以允许:abstract base classes。
你正在处理类,而不是类的实例。那是你要的吗? – robert
“我期望避免创建实例,因为我稍后使用该功能。”严重的错误观念。请找一个关于面向对象设计的更好的教程。 –