Python 全局变量在模块级别未定义
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26773932/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Global variable is undefined at the module level
提问by Daniel Cazan
(There are many similar and more generic questions, been trying the solutions from them after reading through them, can't get them working so asking here as a more situation-specific version of what I'm seeing)
(有许多类似和更通用的问题,在通读它们后尝试了它们的解决方案,无法让它们工作,因此在此处询问我所看到的情况的特定版本)
I think I am really miss-understanding how Python does OOP due to my more C#/C++ background. So here's what I'm trying to do right this moment.
由于我有更多的 C#/C++ 背景,我想我真的很想念 Python 如何执行 OOP。所以这就是我此刻正在努力做的事情。
I'm starting with two modules to set up the rest of my project, partially as a sanity-check and proof-of-concept. One module logs things to a file as I go while also storing data from multiple modules (to eventually package them all and dump them on request) Doing all this in PyCharm and mentioning the error warnings it suggests by the way, and using Python 2.7
我从两个模块开始设置我的项目的其余部分,部分是作为完整性检查和概念验证。一个模块在我运行时将内容记录到一个文件中,同时还存储来自多个模块的数据(最终将它们全部打包并根据要求转储它们)在 PyCharm 中完成所有这些并顺便提及它建议的错误警告,并使用 Python 2.7
Module 1:
src\helpers\logHelpers.py
class LogHelpers:
class log:
def classEnter():
#doing stuff
def __init__(self):
self.myLog = LogHelpers.log() #forgot to mention this was here initially
[..] various logging functions and variables to summarize what's happening
__builtin__.mylogger = LogHelpers
Module 2:
src\ULTs\myULTs.py
mylogger.myLog.classEnter()
(both the modules and the root src\ have an empty init.py file in them)
(模块和根 src\ 中都有一个空的init.py 文件)
So according to the totally awesome response here ( Python - Visibility of global variables in imported modules) at this stage this should be working, but 'mylogger' becomes an 'unresolved reference'
因此,根据此处的非常棒的响应(Python - 导入模块中全局变量的可见性),在此阶段这应该可以正常工作,但是“mylogger”变成了“未解析的引用”
So that was one approach. I also tried the more straight forward global one ( Python: How to make a cross-module variable?)
所以这是一种方法。我还尝试了更直接的全局变量(Python: How to make a cross-module variable?)
Module 1:
src\helpers\logHelpers.py
class LogHelpers:
class log:
def classEnter(self):
#doing stuff
def __init__(self):
self.myLog = LogHelpers.log() #forgot to mention this was here initially
[..] various logging functions and variables to summarize what's happening
mylogger = LogHelpers
__init__.py
__all__ = ['LogHelpers', hexlogger]
from .logHelpers import *
Module 2:
src\ULTs\myULTs.py
from helpers import mylogger
mylogger.myLog.classEnter()
This version gets a "parameter 'self' unfilled" error on the classEnter, which various reports seem to indicate means that mylogger is un-initialized (misleading error code but that's what it seems to mean)
此版本在 classEnter 上出现“参数‘self’未填充”错误,各种报告似乎表明这意味着 mylogger 未初始化(误导性错误代码,但这似乎是什么意思)
And then I tried this..
然后我尝试了这个..
Module 1:
src\helpers\logHelpers.py
class LogHelpers:
class log:
def classEnter(self):
#doing stuff
def __init__(self):
self.myLog = LogHelpers.log() #forgot to mention this was here initially
[..] various logging functions and variables to summarize what's happening
__mylogger = LogHelpers
__init__.py
__all__ = ['LogHelpers', hexlogger]
from .logHelpers import *
Module 2:
src\ULTs\myULTs.py
from helpers import mylogger
def someFunction(self):
global mylogger
mylogger.myLog.classEnter()
And this version gets the 'Global variable is undefined at the module level' error when I hover of global mylogger.
当我将鼠标悬停在全局 mylogger 上时,此版本会出现“在模块级别未定义全局变量”错误。
Then there is the idea of each other module tracking its own instance of a class apparently, if I end up having to I can go with that method and coordinate them.. but that's kind of a hack considering what I'm trying to do.
然后是每个其他模块显然跟踪自己的类实例的想法,如果我最终不得不使用该方法并协调它们..但考虑到我正在尝试做的事情,这是一种黑客行为。
That's kind of where I'm at, that's the gist of what I'm trying to do... I'm reading through as many similar questions as I can but all of them seem to come back to these kinda of solutions (which don't seem to be working) or saying 'don't do that' (which is generally good advice but I'm not really grocking the preferred Pythony way of keeping multiple ongoing non-static classes organized for a large project - other than shoving them all in one directory)
这就是我所处的位置,这就是我想要做的事情的要点......我正在阅读尽可能多的类似问题,但所有这些问题似乎都回到了这些解决方案(其中似乎没有工作)或说“不要那样做”(这通常是好的建议,但我并没有真正探索为大型项目组织多个正在进行的非静态类的首选 Pythony 方式 - 除了将它们全部放在一个目录中)
Thoughts? (How badly am I mangling Python here?)
想法?(我在这里破坏 Python 有多严重?)
[EDIT] Based on feedback tried a mini version that eliminated the inner classes completely: Ok, so did a local mini-class based on what you said:
[编辑] 根据反馈尝试了一个完全消除内部类的迷你版本:好的,根据您所说的,本地迷你类也是如此:
class testClass:
def __init__(self):
self.testVar = 2
def incrementVar(self):
self.testVar += 1
myClass = testClass()
Set it up via init.py
通过init.py 进行设置
__all__ = [myClass]
from .logHelpers import myClass
Went to other module and
转到其他模块和
from helpers import myClass
class Test_LogHelpers(unittest.TestCase):
def test_mini(self):
myClass.incrementVar()
Ran it directly instead of looking at PyCharm, no Global anything.. NameError: name 'myClass is not defined
直接运行它而不是查看 PyCharm,没有全局任何东西.. NameError: name 'myClass is not defined
So still at square one :( (and still need to store state)
所以仍然在第一个:((仍然需要存储状态)
[EDIT] Adding Traceback:
[编辑] 添加回溯:
Traceback (most recent call last):
File "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 3.4.1\helpers\pycharm\utrunner.py", line 124, in <module> module = loadSource(a[0])
File "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 3.4.1\helpers\pycharm\utrunner.py", line 40, in loadSource module = imp.load_source(moduleName, fileName)
File "C:\[...mylocation...]\py\src\ULTs\LogHelpers_ULT.py", line 3, in <module> from helpers import myClass
File "C:\[...mylocation...]\py\src\helpers\__init__.py", line 7, in <module>
__all__ = [myClass]
NameError: name 'myClass' is not defined
============================================================================
================================================== ==========================
kk, I got it working with the miniclass. I don't know why the other approach / approaches was not working, but this seemed to fix things. (Resources: http://docs.python-guide.org/en/latest/writing/structure/, http://mikegrouchy.com/blog/2012/05/be-pythonic-__init__py.html)
kk,我让它与迷你班一起工作。我不知道为什么其他方法/方法不起作用,但这似乎可以解决问题。(资源:http: //docs.python-guide.org/en/latest/writing/structure/,http: //mikegrouchy.com/blog/2012/05/be-pythonic-__init__py.html)
**logHelpers.py**
[... some static logging functionality ...]
class testClass:
def __init__(self):
self.testVar = 2
def incrementVar(self, source):
self.testVar += 1
mylogger.myLog.info(source + " called, new val: " + str(self.testVar))
myClass = testClass()
**test_LogHelpers_ULT.py**
import unittest
from helpers.logHelpers import myClass
class Test_LogHelpers(unittest.TestCase):
def test_mini(self):
myClass.incrementVar("LogHelpers")
For some reason skipping the init.py (and leaving it blank) and going for the explicit importation worked. It also maintained state - I created a duplicate of the test file and my log output correctly had '3' for the first file to call the helper, and '4' for the second file to call the helper.
出于某种原因,跳过 init.py (并将其留空)并进行显式导入工作。它还保持状态 - 我创建了测试文件的副本,并且我的日志输出正确地为第一个文件调用帮助程序为“3”,为第二个文件调用帮助程序为“4”。
Thanks Daniel Roseman for the help and suggestions, they had me look a bit more in the right direction. If you can spot why the previous stuff wasn't working it would be much appreciate just to add to my understanding of this language, but I'm gonna go ahead and mark your answer as 'Answered' since it had some very useful feedback.
感谢 Daniel Roseman 的帮助和建议,他们让我朝着正确的方向前进了一点。如果你能发现为什么以前的东西不起作用,那么我会非常感谢增加我对这种语言的理解,但我会继续将你的答案标记为“已回答”,因为它有一些非常有用的反馈。
采纳答案by Daniel Roseman
Before I start, note that the PyCharm warnings are not actual Python errors: if you ran your code, you would probably get more useful feedback (remember static analysis of a dynamic language like Python can only get you so far, many things can't be resolved until you actually run the code).
在开始之前,请注意 PyCharm 警告并不是实际的 Python 错误:如果您运行您的代码,您可能会得到更多有用的反馈(请记住,像 Python 这样的动态语言的静态分析只能让您到此为止,许多事情不能在您实际运行代码之前解决)。
Firstly, it's really not clear why you have nested classes here. The outer class seems completely useless; you should remove it.
首先,真的不清楚你为什么在这里嵌套类。外部类似乎完全没用;你应该删除它。
The reason for the error message about "self" is that you have defined an instance method, which can only be called on an instance of log. You could make mylogger(absolutely no need for the double-underscore prefix) an instance: mylogger = log()- and then import that, or import the class and instantiate it where it is used.
关于“self”的错误信息的原因是您定义了一个实例方法,该方法只能在 的实例上调用log。您可以创建mylogger(绝对不需要双下划线前缀)一个实例:mylogger = log()- 然后导入它,或者导入类并在使用它的地方实例化它。
So in your first snippet, the error message is quite clear: you have not defined mylogger. Using my recommendation above, you can do from helpers import myloggerand then directly call mylogger.classEnter().
因此,在您的第一个代码段中,错误消息非常清楚:您尚未定义mylogger. 使用我上面的建议,您可以执行from helpers import mylogger然后直接调用mylogger.classEnter().
Finally, I can't see what that globalstatement is doing in someFunction. There's no need to declare a name as global unless you plan to reassign it within your scope and have that reassignment reflected in the global scope. You're not doing that here, so no need for global.
最后,我看不到该global语句在someFunction. 没有必要将名称声明为全局名称,除非您计划在您的范围内重新分配它并在全局范围内反映该重新分配。你不会在这里这样做,所以不需要global.
By the way, you should also question whether you even need the inner logclass. Generally speaking, classes are only useful when you need to store some kind of state in the object. Here, as your docstring says, you have a collection of utility methods. So why put them in a class? Just make them top-level functions inside the logHelpersmodule (incidentally, Python style prefers lower_case_with_underscorefor module names, so it should be "log_helpers.py").
顺便说一句,您还应该质疑您是否甚至需要内部log类。一般来说,类只在需要在对象中存储某种状态时才有用。在这里,正如您的文档字符串所说,您有一组实用方法。那么为什么要把它们放在一个类中呢?只需将它们设为logHelpers模块内的顶级函数(顺便说一句,Python 风格更喜欢lower_case_with_underscore模块名称,因此它应该是“log_helpers.py”)。

