Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python3在initialisaton访问生成器中的类属性_Python_Python 3.x_Class_Namespaces - Fatal编程技术网

python3在initialisaton访问生成器中的类属性

python3在initialisaton访问生成器中的类属性,python,python-3.x,class,namespaces,Python,Python 3.x,Class,Namespaces,我目前正在将codebase从python2切换到python3,遇到了一个我不太理解的问题: class MyClass: var1 = True var2 = tuple([i for i in [1, 2,] if var1]) 上述班级在python2中运行得非常愉快,但在python3中中断了 我把它改成: class MyClass: var1 = True var2 = tuple(i for i in [1, 2,] if var1) 因为我的

我目前正在将
codebase
从python2切换到python3,遇到了一个我不太理解的问题:

class MyClass:
    var1 = True
    var2 = tuple([i for i in [1, 2,] if var1])
上述班级在python2中运行得非常愉快,但在python3中中断了

我把它改成:

class MyClass:
    var1 = True
    var2 = tuple(i for i in [1, 2,] if var1)
因为我的理解是,列表理解是多余的,不管它是否起作用。经过一些调查,似乎理解在初始化类的主体中的行为方式我不太理解

# Breaks in python 2 and 3
class MyClass:
    var1 = True
    var2 = tuple(i for i in [1, 2,] if var1)


# Works in python 2, breaks in 3
class MyClass:
    var1 = True
    var2 = [i for i in [1, 2,] if var1]

有没有关于发生了什么的指针?

关于第一种情况,实际上是将生成器表达式传递给一个甚至不是类属性的
元组
函数。它实际上类似于以下代码:

>>> class MyClass:
...     var1 = True
...     def func():
...         return var1
...     func()
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in MyClass
  File "<stdin>", line 4, in func
NameError: global name 'var1' is not defined
>>类MyClass:
...     var1=真
...     def func():
...         返回变量1
...     func()
... 
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“”,第5行,在MyClass中
文件“”,第4行,在func中
NameError:未定义全局名称“var1”
正如您所看到的,在Python-2.7和3.X中再次出现了
namererror
。原因是函数有自己的名称空间,并且没有明确声明该变量的状态(全局、局部、非局部),也没有通过类的实例访问(
self.var1
)函数,因此无法访问外部有界名称空间


另一方面,在python-2中,列表理解可以访问定义它们的对象的名称空间。它们不像函数,也没有函数所具有的许多特性。这实际上是一种双边关系。这就是说,虽然您可以在列表理解内部使用变量,但您在列表理解内部定义的内容也可以在列表理解外部访问。由于人们倾向于在列表理解中使用一次性变量,这将导致代码出现变量泄漏。但由于Python-3.x列表理解从函数中借用了私有名称空间,因此它们可以拥有自己的名称空间

我不相信这个问题完全是附加dup的翻版,但除非其他人这样做,否则我不会重新打开它。@Kasramvd你能详细说明一下吗?我认为Martijn的答案涵盖了OP可能想知道的一切。@Aran Fey是的,答案很全面,但我的意思是这个问题不是重复的。复制基本上是为了回答问题。虽然有人会说,当你能在另一个不重复的问题中找到答案,那么不重复又有什么意义呢。但是,当你基于一个特定的根启动一个线程时,它将产生它自己的结果,而且,对于这样的问题,由于自3.1以来Python有很多更新的版本,并且所有的都有很多新功能,你可以建议更多更新的答案。@Aran Fey all-in-one,我的意思是,像这样解决语言的一些基本问题的非琐碎的好问题总是值得讨论和回顾。@Kasramvd我现在明白了,你说这是一个不同的问题,因为它问的是列表理解和生成器表达式之间的区别。但我不认为这是重新提出这个问题的充分理由。这只是对“为什么这个列表理解在python2中有效而在python3中无效”这个问题提出了一个不同的解释——这是因为列表理解在python2中没有自己的作用域,但是生成器表达式有自己的作用域。“为什么列表理解不同于生成器表达式?”的答案实际上只是“因为它们是不同的表达式”。很有趣,谢谢!是否有一个共同的模式来完成当前被破坏的代码所做的事情,或者是完全重新思考逻辑并将其移动到
\uuuu init\uuuu
或类似的地方?@ptr从OOP的角度来看,最好将变量移动到一个
\uuu init\uuuu
中,它很容易访问,并且您对它有更多的控制权。除非,它的成本太高,这在这种情况下是非常不可能的。