我使用我的testmodule中的类方法对全局变量有疑问
示例: 我的测试模块的文本:
cat ./testmodule.py
class testclass(object):
def __init__(self):
self.testfunc()
def testfunc(self):
print(' '.join(globals()).split(' '))
我的测试课的文字相同:
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']
完美,我看到了我的aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
>>> 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']
>>>
嘿!慢慢来! WTF?变量丢失。
请帮帮我 我如何从testmodule像testclass和testfunc获得相同的结果?
答案 0 :(得分:0)
扩展@chepner的注释:globals()
仅返回当前模块的模块级变量。
testfunc()
时,它被定义为__main__.testfunc
,调用globals()
实质上会返回__main__.__dict__
。testmodule
中定义时,它定义为testmodule.testfunc
,并且globals()
返回testmodule.__dict__
。如果要testfunction
访问另一个模块的全局变量,则需要确保在模块的词法范围内调用globals()
。最简单的方法是扩展testfunction
以将字典作为参数:
## testmodule.py
def testfunc(globals_):
print(globals)
## REPL or other module
import testmodule
testmodule.testfunc(globals())
__main__
。您需要import __main__
才能使用它。但是您可以看到,当前模块从变量__main__
命名为__name__
。python somescript.py
时,文件的内容作为__main__
模块而不是somescript
模块执行。 Python具有闭包,模块内部的功能在本质上就像模块范围内的闭包一样,因此我希望globals()
是每个模块的成员。那么以下内容将产生预期的结果:
%% testmodule.py
def testfunc(globals_):
print(_globals())
%% REPL
import testmodule
testmodule.testfunc(globals)
但同样,这仅返回testmodule的全局变量。相反,globals
仅在__builtin__
中定义,并且似乎将调用方的范围用作隐藏参数。结果:
## REPL
import testmodule
testmodule.testfunc(globals) # prints testmodule.__dict__
testmodule.testfunc(lambda: globals()) # prints __main__.__dict__
通常期望f
和lambda: f()
得到相同的结果。
您不能依靠somemodule.__dict__
进行定义。导入模块时,模块实际上可能选择返回一些包装对象,而不是普通的模块对象。实际上,没有任何东西可以证明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'>