模块中类的方法看不到我的globals()

2024-05-01 22:03:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我在使用testmodule中的class方法时遇到了一个globals问题

示例: 我的测试模块文本:

猫/测试模块.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']

太好了,我看到了我的aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

>>> 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相同的结果?你知道吗


Tags: name文本selfobjectinitdefclasssplit
1条回答
网友
1楼 · 发布于 2024-05-01 22:03:10

在@chepner的注释上展开:globals()只返回当前模块的模块级变量。你知道吗

  • 在REPL中定义testfunc()时,它被定义为__main__.testfunc,调用globals()基本上返回__main__.__dict__。你知道吗
  • testmodule中定义时,它被定义为testmodule.testfuncglobals()返回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)
    

    但同样,它只返回testmodule的globals。相反,globals只在__builtin__中定义,似乎使用调用者的作用域作为隐藏参数。因此:

    ## REPL
    import testmodule
    testmodule.testfunc(globals) # prints testmodule.__dict__
    testmodule.testfunc(lambda: globals())  # prints __main__.__dict__
    

    通常期望flambda: 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'>
    

相关问题 更多 >