【发布时间】:2012-11-03 07:48:17
【问题描述】:
这困扰了我几个小时,因为我来自 C++ 世界。我终于发现了发生了什么,但我不知道为什么这是默认行为。我想了解为什么这种语言是这样设计的。
我想要一个实例变量mem。所以我尝试了这个:
class x(object):
mem = []
obj = x()
obj.mem.append(1)
print(obj.mem)
objTWO = x()
objTWO.mem.append(2)
print(objTWO.mem)
打印这个:
[1]
[1, 2]
鉴于:
class x(object):
def __init__(self):
self.mem = []
obj = x()
obj.mem.append(1)
print(obj.mem)
objTWO = x()
objTWO.mem.append(2)
print(objTWO.mem)
打印
[1]
[2]
为什么第一个是默认行为?这里的直觉是什么,因为它与许多主流 OO 语言的工作相反(他们为大写引入了 static 关键字,这让你明确地说你想要一个静态变量)?对于 Python 的新手来说,这是一个惊喜。
此外,您似乎可以拥有同名的实例变量和类变量:
class x(object):
mem = []
def __init__(self):
self.mem = []
我必须运行它才能确定要打印的内容。我什至无法猜测!
【问题讨论】:
-
其他语言工作方式的直觉是什么?不同的语言做事不同,看起来你只是习惯了另一种方式。
-
看起来不对,因为你带了行李。这实际上是合乎逻辑的:在
class ...:之后,字段是类变量。只有在实例初始化器中声明实例变量才有意义。当然,这不是 C++/Java 的思维方式,但完全可以理解。 -
没有“默认行为”。只有一种替代方案有点类似于其他语言中可用的语法(可能不是故意的)。对我来说,这个句法特征的行为很有意义:类属性是绑定在类级别的属性,定义一个属性是通过在类定义级别进行分配来完成的——在与方法相同的级别,这也住在班里。这也完全符合没有声明的事实,并且所有看起来像声明的东西,在每个层面上都是一个声明。
-
我在 Java 中遇到了同样的问题 ;) 但我是这么想的:如果你没有像 static、private、public 这样的可见性修饰符,你怎么能区分变量的范围?您明确声明:self.
= ...范围/命名空间 self 中的变量 获取值 。面向对象只是一个概念,取决于语言设计者如何解释/实现它。
标签: java python class instance-variables