模块中 class 的方法看不到我的 globals()
Method of class in module doesn't see my globals()
我在使用测试模块
中的class方法时遇到全局问题
示例:
我的测试模块的文本:
猫./testmodule.py
class testclass(object):
def __init__(self):
self.testfunc()
def testfunc(self):
print(' '.join(globals()).split(' '))
我的测试文本class相同:
class testclass(object):
def __init__(self):
self.testfunc()
def testfunc(self):
print(' '.join(globals()).split(' '))
我的测试函数的文本,没有新内容:
def testfunc():
print(' '.join(globals()).split(' '))
然后去测试它。
Python 3.6.6 (default, Aug 13 2018, 18:24:23)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>>
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa='a'
>>>
>>> import testmodule
>>>
>>> class testclass(object):
... def __init__(self):
... self.testfunc()
...
... def testfunc(self):
... print(' '.join(globals()).split(' '))
...
>>> def testfunc():
... print(' '.join(globals()).split(' '))
万事俱备,开始测试
>>> testfunc()
['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'testmodule', 'testclass', 'testfunc']
变量存在
>>> testclass.testfunc(testclass)
['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'testmodule', 'testclass', 'testfunc']
同样的结果,变量存在
>>> testmodule.testclass.testfunc(testclass)
['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__file__', '__cached__', '__builtins__', 'testclass']
>>>
变量丢失。
如何从 testmodule 获得与 testclass 和 testfunc 相同的结果?
扩展@chepner 的评论:globals()
return仅当前模块的模块级变量。
- 当您在 REPL 中定义
testfunc()
时,它被定义为 __main__.testfunc
并调用 globals()
returns 本质上是 __main__.__dict__
.
- 在你的
testmodule
中定义时,定义为testmodule.testfunc
和globals()
returns testmodule.__dict__
.
如果你想testfunction
访问另一个模块的全局变量,你需要确保在模块的词法范围内调用globals()
。最简单的是扩展 testfunction
以期望字典作为参数:
## testmodule.py
def testfunc(globals_):
print(globals)
## REPL or other module
import testmodule
testmodule.testfunc(globals())
其他详细信息
默认情况下未定义 __main__
。您需要 import __main__
才能使用它。但是从变量__name__
. 可以看出当前模块的名字是__main__
- 当您 运行
python somescript.py
时,文件的内容作为 __main__
模块执行,而不是作为 somescript
模块执行。
Python 有闭包,模块内的函数本质上就像模块范围内的闭包——所以我希望 globals()
成为每个模块的成员。那么以下将产生预期的结果:
%% testmodule.py
def testfunc(globals_):
print(_globals())
%% REPL
import testmodule
testmodule.testfunc(globals)
但是,这 return 只是测试模块的全局变量。相反 globals
仅在 __builtin__
中定义,并且似乎使用调用者的范围作为隐藏参数。结果:
## REPL
import testmodule
testmodule.testfunc(globals) # prints testmodule.__dict__
testmodule.testfunc(lambda: globals()) # prints __main__.__dict__
通常期望 f
和 lambda: f()
具有相同的结果。
你不能依赖somemodule.__dict__
来定义。当您导入一个模块时,它实际上可能会选择 return 一些包装器对象而不是普通的模块对象。实际上,甚至没有任何东西强制 somemodule
具有典型的模块语义!例如。试用模块:
## somemodule.py -- Please don't actually do this.
import sys
sys.modules["somemodule"] = "not a module"
## REPL
>>> import somemodule
>>> somemodule
'not a module'
此类更改的真实示例是 os.path
:
>>> import os.path
>>> os.path
<module 'ntpath' from 'C:\tools\msys64\mingw64\lib\python2.7\ntpath.pyc'>
我在使用测试模块
中的class方法时遇到全局问题示例: 我的测试模块的文本:
猫./testmodule.py
class testclass(object):
def __init__(self):
self.testfunc()
def testfunc(self):
print(' '.join(globals()).split(' '))
我的测试文本class相同:
class testclass(object):
def __init__(self):
self.testfunc()
def testfunc(self):
print(' '.join(globals()).split(' '))
我的测试函数的文本,没有新内容:
def testfunc():
print(' '.join(globals()).split(' '))
然后去测试它。
Python 3.6.6 (default, Aug 13 2018, 18:24:23)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>>
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa='a'
>>>
>>> import testmodule
>>>
>>> class testclass(object):
... def __init__(self):
... self.testfunc()
...
... def testfunc(self):
... print(' '.join(globals()).split(' '))
...
>>> def testfunc():
... print(' '.join(globals()).split(' '))
万事俱备,开始测试
>>> testfunc()
['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'testmodule', 'testclass', 'testfunc']
变量存在
>>> testclass.testfunc(testclass)
['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'testmodule', 'testclass', 'testfunc']
同样的结果,变量存在
>>> testmodule.testclass.testfunc(testclass)
['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__file__', '__cached__', '__builtins__', 'testclass']
>>>
变量丢失。
如何从 testmodule 获得与 testclass 和 testfunc 相同的结果?
扩展@chepner 的评论:globals()
return仅当前模块的模块级变量。
- 当您在 REPL 中定义
testfunc()
时,它被定义为__main__.testfunc
并调用globals()
returns 本质上是__main__.__dict__
. - 在你的
testmodule
中定义时,定义为testmodule.testfunc
和globals()
returnstestmodule.__dict__
.
如果你想testfunction
访问另一个模块的全局变量,你需要确保在模块的词法范围内调用globals()
。最简单的是扩展 testfunction
以期望字典作为参数:
## testmodule.py
def testfunc(globals_):
print(globals)
## REPL or other module
import testmodule
testmodule.testfunc(globals())
其他详细信息
-
默认情况下未定义
__main__
。您需要import __main__
才能使用它。但是从变量__name__
. 可以看出当前模块的名字是- 当您 运行
python somescript.py
时,文件的内容作为__main__
模块执行,而不是作为somescript
模块执行。 Python 有闭包,模块内的函数本质上就像模块范围内的闭包——所以我希望
globals()
成为每个模块的成员。那么以下将产生预期的结果:%% testmodule.py def testfunc(globals_): print(_globals()) %% REPL import testmodule testmodule.testfunc(globals)
但是,这 return 只是测试模块的全局变量。相反
globals
仅在__builtin__
中定义,并且似乎使用调用者的范围作为隐藏参数。结果:## REPL import testmodule testmodule.testfunc(globals) # prints testmodule.__dict__ testmodule.testfunc(lambda: globals()) # prints __main__.__dict__
通常期望
f
和lambda: f()
具有相同的结果。你不能依赖
somemodule.__dict__
来定义。当您导入一个模块时,它实际上可能会选择 return 一些包装器对象而不是普通的模块对象。实际上,甚至没有任何东西强制somemodule
具有典型的模块语义!例如。试用模块:## somemodule.py -- Please don't actually do this. import sys sys.modules["somemodule"] = "not a module" ## REPL >>> import somemodule >>> somemodule 'not a module'
此类更改的真实示例是
os.path
:>>> import os.path >>> os.path <module 'ntpath' from 'C:\tools\msys64\mingw64\lib\python2.7\ntpath.pyc'>
__main__