【问题标题】:Python class and global vs local variables [duplicate]Python类和全局变量与局部变量[重复]
【发布时间】:2015-08-19 05:01:47
【问题描述】:

我无法理解以下代码的结果发生了什么:

my_str = "outside func"
def func():
    my_str = "inside func"
    class C():
        print(my_str)
        print((lambda:my_str)())
        my_str = "inside C"
        print(my_str)

输出是:

outside func
inside func
inside C

另外一段代码是:

my_str = "not in class"
class C:
    my_str = "in the class"
    print([my_str for i in (1,2)])
    print(list(my_str for i in (1,2)))

输出是:

[‘in the class’, 'in the class’]
['not in class’, 'not in class’]

问题是:

  1. 每个 print() 语句中发生了什么?
  2. 谁能解释为什么 print() 语句从不同的命名空间获取字符串?

编辑 1:

我认为这与 this question 不同,因为我谦虚地认为那里的答案并不能解释这种变化:

my_str = "outside func"
def func():
    my_str = "inside func"
    class C():
        print(my_str)
        print((lambda:my_str)())
       #my_str = "inside C"
        print(my_str)

输出是:

inside func
inside func
inside func

编辑 2:

确实,这是 this question 的副本,因为正如 Martijn Pieters 所说:

那里的答案是:如果在类体内分配了一个名称, 几乎在一开始。您分配给 my_str,使其大小写相同 在那里。注释掉该行意味着您不再分配 到 my_str,使其大小写与 x 相同。


【问题讨论】:

  • @MartijnPieters Antti 的精彩回答涵盖了第一种情况。第二种情况是这样的,但它并不是一个完全的骗局。也许我会将那个链接留给未来的访问者来回答这个问题。 (你已经准备好了仪式草案;))
  • @BhargavRao:对不起,我实际上假设您链接到Short Description of Python Scoping Rules!这确实是一个骗局。

标签: python class namespaces global-variables


【解决方案1】:

这里有四个作用域:

  1. 全球范围
  2. 函数作用域
  3. 类主体
  4. lambda 范围

当创建一个类语句时,类主体作为函数执行,并且该“函数”的本地命名空间用作类属性。

但是,类主体不是作用域,因此其行为与函数不同。在函数体中,绑定定义了作用域;分配给函数中的名称,并将其标记为本地。在课堂中,分配给一个名称会使其成为一个全局,直到您真正完成分配为止。

所以您的 first print() 调用会发现 my_str 是一个全局变量,因为 later 在您绑定到该名称的类主体中。这是类主体不参与作用域的结果。

接下来,您定义一个 lambda 并调用它。 my_str 从未在该 lambda 中分配,因此必须在父作用域中找到它。这里的类体不是作用域,下一个作用域是函数作用域。这就是该行打印inside func 的原因。

最后,您在类主体中指定本地名称 my_str,并打印该本地名称。

在您删除分配的那一刻,类中的名称被视为非本地名称;第一个和最后一个 print() 语句现在相等,名称只是根据正常范围规则查找。

【讨论】:

  • 你能扩展你的答案来解释 Edit1 的变化吗?
  • @PabloGalindoSalgado:您的编辑仅确认该帖子是骗子。
  • 那我很抱歉。我读了两次答案,不理解这种变化....但正如你所说的那样直截了当。喝咖啡的时间。 :(
  • @PabloGalindoSalgado:那里的答案是:如果在类主体中分配了名称,几乎在开始时。您分配给my_str,使其与那里的y 相同。注释掉该行意味着您不再分配给my_str,使其与x 相同。
  • 今天我不够小心。我很抱歉,很抱歉造成混乱。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-24
  • 2019-06-05
  • 2021-11-11
  • 2018-10-26
  • 1970-01-01
相关资源
最近更新 更多