全局变量在模块级别未定义

时间:2014-11-06 07:28:18

标签: python module scope global-variables

(有许多相似且更通用的问题,在阅读完它们之后尝试过它们的解决方案,无法让它们正常工作,所以在这里要求提供更具特定情况的我看到的版本)

我认为我真的很想念 - 由于我更多的C#/ C ++背景,Python如何处理OOP。所以,这就是我现在正在努力做的事情。

我从两个模块开始设置项目的其余部分,部分是作为一个完整性检查和概念验证。一个模块将内容记录到文件中,同时还存储来自多个模块的数据(最终将它们全部打包并根据请求转储它们)在PyCharm中完成所有这些并提及它所暗示的错误警告,并使用Python 2.7 < / p>

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()

(模块和root src \中都有一个空的 init .py文件)

所以根据这个阶段(Python - Visibility of global variables in imported modules)的完全响应,这应该是有效的,但是&#39; mylogger&#39;成为一个未解决的参考&#39;

这是一种方法。我也尝试过更直接的全球性(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()

此版本获得&#34;参数&#39; self&#39;未填充的&#34; classEnter上的错误,各种报告似乎表示mylogger未初始化(误导性错误代码,但这似乎意味着什么)

然后我试了一下..

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()

此版本的“全局变量”未在模块级别定义&#39;我悬停全球mylogger时出错。

然后有一个想法是每个其他模块显然跟踪它自己的一个类的实例,如果我最终不得不使用那个方法并协调它们..但那是一种考虑什么的hack我试图这样做。

这就是我所处的地方,这是我尝试做的事情的要点......我正在阅读尽可能多的类似问题。我可以,但他们似乎都回到了这些解决方案(似乎没有工作)或者说“不要这样做”#39; (这通常是一个很好的建议,但我并没有真正讨厌为大型项目保留多个正在进行的非静态类的Pythony方法 - 除了将它们全部放在一个目录中之外)

思考? (我在这里修改Python有多糟糕?)

[编辑]根据反馈尝试了一个完全消除内部类的迷你版本: 好吧,基于你所说的当地小型班也是如此:

class testClass:
    def __init__(self):
        self.testVar = 2
    def incrementVar(self):
        self.testVar += 1
myClass = testClass()

通过 init .py

进行设置
__all__ = [myClass]
from .logHelpers import myClass

去了其他模块和

from helpers import myClass
class Test_LogHelpers(unittest.TestCase):
    def test_mini(self):
        myClass.incrementVar()

直接使用它而不是查看PyCharm,没有全局任何东西.. NameError: name 'myClass is not defined

所以仍然在方形一:((并且仍然需要存储状态)

[编辑]添加回溯:

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,我让它与小型机一起工作。我不知道为什么其他方法/方法不起作用,但这似乎解决了问题。 (资源: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")

出于某种原因跳过了     的初始化的.py (并将其留空)并进行明确的输入工作。它还保持状态 - 我创建了测试文件的副本,我的日志输出正确地具有&#39; 3&#39;对于第一个调用助手的文件,&#39; 4&#39;为第二个文件调用帮助器。

感谢丹尼尔罗斯曼的帮助和建议,他们让我看起来更朝正确的方向。如果你能发现为什么以前的东西不能正常工作,那么只要增加我对这种语言的理解就会非常感激,但我会继续把你的答案标记为“已回答&#39 ;因为它有一些非常有用的反馈。

1 个答案:

答案 0 :(得分:11)

在开始之前,请注意PyCharm警告不是实际的Python错误:如果你运行代码,你可能会得到更多有用的反馈(记得像Python这样的动态语言的静态分析只能让你到目前为止,很多东西在您实际运行代码之前无法解决。)

首先,它真的不清楚为什么你在这里有嵌套类。外层阶级似乎完全没用;你应该删除它。

关于&#34; self&#34;的错误消息的原因是你定义了一个实例方法,只能在log的实例上调用。您可以使mylogger(绝对不需要双下划线前缀)实例:mylogger = log() - 然后导入该实例,或者导入该类并将其实例化到使用它的位置。

因此,在您的第一个代码段中,错误消息非常明确:您尚未定义mylogger。使用上面的建议,您可以from helpers import mylogger,然后直接拨打mylogger.classEnter()

最后,我无法看到global语句在someFunction中的作用。除非您计划在范围内重新分配名称并将该重新分配反映在全局范围内,否则无需将名称声明为全局名称。你不是在这里做的,所以不需要global

顺便说一下,您还应该质疑是否需要内部log类。一般来说,只有在需要在对象中存储某种状态时,类才有用。在这里,正如您的docstring所说,您有一组实用方法。那么为什么要把它们放在课堂上呢?只需在logHelpers模块中创建顶级函数(顺便说一下,Python样式更喜欢lower_case_with_underscore模块名称,因此它应该是&#34; log_helpers.py&#34;)。