【问题标题】:Class vs instance initialization in Python [duplicate]Python中的类与实例初始化[重复]
【发布时间】:2017-02-09 03:30:18
【问题描述】:

我有点疑惑,为什么在 Python 中初始化一个类的实例时,我不能使用类属性。示例如下:

class TestClass:
... shared_list = ['a', 'b', 'c']
... def __init__(self):
...     self.length = len(shared_list)

现在

>>> TestClass.shared_list
['a', 'b', 'c']

所以列表在类的任何实例出现之前就存在了,但是

>>> tc = TestClass()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in __init__
NameError: global name 'shared_list' is not defined

我错过了一些简单的东西吗?

UPD:感谢大家的帮助和及时回复。我已经消除了我的困惑:类在 Python 中没有定义范围。

【问题讨论】:

  • 如果你想要作用域的shared_list,你需要self.shared_listTestClass.shared_list
  • @AChampion 谢谢,把 TestClass.shared_list 修复它。来自 C++,我仍然觉得它很混乱,我需要一个明确的类的引用 within。我想如果在实例中找不到属性,就会在类中搜索,而不是全局搜索,不是吗?
  • 很遗憾没有,请参阅上面的范围规则。

标签: python class oop


【解决方案1】:

class 定义不会为其方法创建新范围,只是为局部变量创建命名空间。这在一定程度上记录在Class Definition Syntax

当一个类定义被输入时,一个新的命名空间被创建,并且 用作局部作用域——因此,对局部变量的所有赋值都去 进入这个新的命名空间。特别是,函数定义绑定 此处为新函数的名称。

当一个类定义正常离开时(通过结尾),一个类对象 被建造。这基本上是围绕 由类定义创建的命名空间。

这就是为什么您需要在其方法中将类属性引用为TestClass.shared_listself.shared_list

【讨论】:

  • 谢谢,这正是我困惑的根源。
【解决方案2】:

问题出现在您的 __init__ 函数中,该函数在您实例化 TestClass 时被调用。

__init__ 函数使用shared_list 变量,但实际上这个变量只能在绑定到实例或基类本身时使用。如果你想修改共享变量,你必须用类名来调用它:

def __init__(self):
    self.length = len(TestClass.shared_list)

如果您只想修改该实例的变量,则必须将其声明为实例变量:

def __init__(self):
    self.not_shared_list = ['a', 'b', 'c']
    self.length = len(self.not_shared_list)

【讨论】:

  • 注意:self.share_list 将引用TestClass.shared_list,对self.share_list 的任何更改都会修改类变量。
  • @AChampion 谢谢——已作相应修改。
  • 谢谢, - 我赞成你的答案,但我接受了一个不同的答案,因为它恰好解决了我的困惑来源:类不会在 Python 中创建范围。
【解决方案3】:

如果不指定变量shared_list的“环境”,这里是selfTestClass,python认为它是一个全局变量——也没有定义。

使用self.shared_listTestClass.shared_list 引用它。

【讨论】:

    猜你喜欢
    • 2014-03-22
    • 1970-01-01
    • 1970-01-01
    • 2015-12-31
    • 2012-09-21
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    • 1970-01-01
    相关资源
    最近更新 更多