java - 为什么 Python 不使用类 C++/Java 的语法来定义实例变量?

标签 java python class instance-variables

这困扰了我几个小时,因为我来自 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 = []

我必须运行它才能确定要打印的内容。我什至猜不到!

最佳答案

直觉是,在 Python 中,一切 都是对象,包括类本身。 Python 中没有“static”关键字这样的东西;有类,是对象,那些类有属性。 出现在类定义中的所有内容 都是类属性——包括方法和其他类型的属性。

这种设计的好处是简单和一致。公共(public)或私有(private)之间没有区别,静态和非静态属性之间也没有区别。类和实例属性之间的区别通过类构造函数自然而然地出现。当__init__被调用(间接通过 ClassName(params) ),它通过 self 接收该类的新实例参数,然后它直接修改该实例。一切都通过已经定义的构造显式发生——您无需了解任何新语法或新关键字即可查看创建实例时发生的情况。

那么你只需要了解 Python 的属性查找模型即可。它的工作原理几乎与 PATH 相同大多数外壳的分辨率。例如,在 bash 中,当您执行命令 ( ls ) 时,会搜索路径中的第一个条目,然后是第二个条目,依此类推,找到的第一个版本的命令就是执行的版本。但在这种情况下,路径看起来像这样(至少在具有单一继承的简单情况下):

instance; class; superclass; superclass; ... and so on

这与 c 或 c++ 中嵌套作用域中的名称解析并没有太大区别。你提示:

Even worse is that it seems you are allowed to have an instance variable and a class variable with the same name.

但这真的比 c 允许您定义 int i; 更令人困惑吗?在一个 block 中,创建一个内部 block ,然后定义另一个 int i;掩盖原来的?

关于java - 为什么 Python 不使用类 C++/Java 的语法来定义实例变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13385194/

相关文章:

java - 确保字段从构造函数中初始化

类之间的 Python 传递变量

python - 如何将 python 日志记录输出重定向到文件而不是标准输出?

java - 使用 JAXB 解码嵌套 XML 元素

Java 硬件加速

java - 如何将 GIT 非 Eclipse Java 项目导入 Eclipse?

java - 我们如何在 selenium java 中检查滚动条是否可滚动?

python - Flask:如何在蓝图中的每条路线之前运行一个方法?

c++ - 是否可以为派生类创建构造函数?

c++ - 什么时候使用指针成员变量?