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

Dan*_*zan 5 python scope module global-variables

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

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

我从两个模块开始设置项目的其余部分,部分是作为一个完整性检查和概念验证.一个模块将内容记录到文件中,同时还存储来自多个模块的数据(最终将它们打包并根据请求转储它们)在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()
Run Code Online (Sandbox Code Playgroud)

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

因此,根据这里非常棒的响应(Python - 导入模块中的全局变量的可见性),这应该是有效的,但是'mylogger'成为'未解析的引用'

这是一种方法.我也尝试过更直接的全局变量(Python:如何制作跨模块变量?)

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()
Run Code Online (Sandbox Code Playgroud)

这个版本在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()
Run Code Online (Sandbox Code Playgroud)

当我将鼠标悬停在全局mylogger上时,此版本会出现"模块级别未定义全局变量"错误.

然后有一个想法,即每个其他模块显然跟踪它自己的一个类的实例,如果我最终不得不使用该方法并协调它们......但考虑到我正在尝试做什么,这就是一种黑客攻击.

这就是我所处的位置,这就是我要做的事情的要点......我正在阅读尽可能多的类似问题,但所有这些问题似乎都回到了这些解决方案(其中似乎没有工作)或说'不要那样做'(这通常是一个很好的建议,但我并没有真正讨厌保留多个正在进行的大型项目的非静态类的Pythony方式 - 除了将它们全部推到一个目录中)

思考?(我在这里破坏Python有多糟糕?)

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

class testClass:
    def __init__(self):
        self.testVar = 2
    def incrementVar(self):
        self.testVar += 1
myClass = testClass()
Run Code Online (Sandbox Code Playgroud)

通过init .py进行设置

__all__ = [myClass]
from .logHelpers import myClass
Run Code Online (Sandbox Code Playgroud)

去了其他模块和

from helpers import myClass
class Test_LogHelpers(unittest.TestCase):
    def test_mini(self):
        myClass.incrementVar()
Run Code Online (Sandbox Code Playgroud)

直接跑它而不是看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
Run Code Online (Sandbox Code Playgroud)

================================================== ==========================

kk,我让它与miniclass一起工作.我不知道为什么其他方法/方法不起作用,但这似乎解决了问题.(参考资料: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")
Run Code Online (Sandbox Code Playgroud)

出于某种原因,跳过 init .py(并将其留空)并进行显式导入工作.它还保持状态 - 我创建了测试文件的副本,我的日志输出正确地为第一个调用助手的文件'3',并为第二个文件调用帮助器'4'.

感谢Daniel Roseman的帮助和建议,他们让我看起来朝着正确的方向前进.如果你能发现为什么以前的东西不能正常工作,那么我会非常感激地加入我对这种语言的理解,但是我会继续把你的答案标记为'已回答',因为它有一些非常有用的反馈.

Dan*_*man 12

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

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

关于"self"的错误消息的原因是您已经定义了一个实例方法,该方法只能在实例上调用log.你可以制作mylogger(绝对不需要双下划线前缀)一个实例:mylogger = log()- 然后导入它,或导入类并在使用它的地方实例化它.

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

最后,我看不出那global句话在做什么someFunction.除非您计划在范围内重新分配名称并将该重新分配反映在全局范围内,否则无需将名称声明为全局名称.你不是在这里做的,所以没必要global.

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