- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
关于name resolution文档不是很清楚。它使用术语 scope 和 namespace 但没有准确说明它们如何生效以及何时引发 NameError
:
When a name is used in a code block, it is resolved using the nearest enclosing scope. The set of all such scopes visible to a code block is called the block’s environment.
When a name is not found at all, a
NameError
exception is raised.
然而,这并没有解释在何处搜索该名称。关于 namespace ,我们得到以下信息:
Names are resolved in the top-level namespace by searching the global namespace, i.e. the namespace of the module containing the code block, [...]
此外,关于__main__
:
The namespace for a module is automatically created the first time a module is imported. The main module for a script is always called
__main__
.
'__main__'
is the name of the scope in which top-level code executes.
结合以上陈述,我想每当在“顶层脚本环境”(“顶层命名空间”)中解析名称时,这通过检查 sys.modules['__main__']
发生这种情况(类似于模块的属性访问如何工作以及如何修改它,如 PEP 562 所指出的)。然而,以下片段表明情况并非如此:
import sys
class Wrapper:
def __init__(self):
self.main = sys.modules['__main__']
def __getattr__(self, name):
try:
return getattr(self.main, name)
except AttributeError:
return 'Fallback for "{}"'.format(name)
sys.modules['__main__'] = Wrapper()
print(undefined)
引发 NameError: name 'undefined' is not defined
。
另一方面,我们可以通过修改 sys.modules['__main__'].__dict__
或使用 setattr
添加名称:
import sys
# Either ...
sys.modules['__main__'].__dict__['undefined'] = 'not anymore'
# Or ...
setattr(sys.modules['__main__'], 'undefined', 'not anymore')
print(undefined) # Works.
所以我怀疑可能是模块的 __dict__
属性(或等效的 __builtins__.globals
)被直接检查,回避了 getattr
模块对象。然而,扩展上面的示例表明情况并非如此:
import sys
class Wrapper:
def __init__(self):
self.main = sys.modules['__main__']
def __getattr__(self, name):
try:
return getattr(self.main, name)
except AttributeError:
return 'Fallback for "{}"'.format(name)
@property
def __dict__(self):
class D:
def __contains__(*args):
return True
def __getitem__(__, item):
return getattr(self, item)
return D()
sys.modules['__main__'] = Wrapper()
sys.modules['builtins'].globals = lambda: sys.modules['__main__'].__dict__
print(globals()['undefined']) # Works.
print(undefined) # Raises NameError.
Wrapper
的示例会失败(虽然它确实适用于“通用”模块属性访问,根据 PEP 562)?最佳答案
你的问题很有趣,因为我没有明确的答案让我们进行一些实验。
首先让我们稍微更改一下您的代码:
# file main.py
import sys
print(sys.modules['__main__'])
class Wrapper:
def __init__(self):
self.main = sys.modules['__main__']
def __getattr__(self, name):
try:
return getattr(self.main, name)
except AttributeError:
return 'Fallback for "{}"'.format(name)
sys.modules['__main__'] = Wrapper()
print(sys.modules['__main__'])
print(undefined)
它会打印
<module '__main__' from 'main.py'>
<__main__.Wrapper object at 0x000001F87601BE48>
Traceback (most recent call last):
File "main.py", line 15, in <module>
print(undefined)
NameError: name 'undefined' is not defined
所以我们仍然有 __main__
作为模块,Wrapper
类在其中。
文档说:
A module’s
__name__
is set equal to__main__
when read from standard input, a script, or from an interactive prompt.
所以这意味着我们的 sys.modules['__main__'] = Wrapper()
行是用来替换一个已经加载的模块,使用来自该模块内部的东西 (!!)。
OTOH,从 REPL 导入 main.py
(创建 __main__
模块的另一种情况),完全弄乱了一切 所以那时正在发生一些替代。
总结:
据我所知,从正在运行的模块内部更改 __main__
需要一些深奥的魔法,也许如果我们使用 importlib.reload
并弄乱缓存模块?
从其他模块这样做似乎没问题,但是(示例)弄乱了事情,并且名称解析中断,即 Wapper 类没有按照您认为应该的方式解析以前的名称。
PD.
很抱歉,如果这不是您想要的有经验的答案并且看起来更像是评论。我这样做是为了检验您的假设并可能找到一些结果。
关于python - 修改 __main__ 模块的属性访问(名称解析的详细信息),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53817898/
假设这样一个函数: In [56]: def add_numbers(x, y): return x + y 当我在没有括号的情况下使用它 In [57]: add_numbers Out[57]:
目前在 Django 网站上工作,我在将类及其属性从我的 models.py 模块导入到我的 views.py 模块时遇到问题音乐应用。据我了解,Django 使用元类来构建模型,因此定义的字段不会作
如果我执行 main.py它工作正常,问题是当我执行 demo2.py |myPackage |subPackage demo.py demo2.py main.p
当前尝试在 Python3 中工作并使用绝对导入将一个模块导入另一个模块,但出现错误 ModuleNotFoundError: No module named '__main__.moduleB';
我有一个 Tornado 应用程序,其文件结构如下: projectfolder |_ Dockerfile |_ src |_ __init__.py |_ __main__.py |_ co
我正在创建一个用于网页抓取的应用程序目录,该目录是在我的 django_project 中抓取的。我在将 models.py 模块中的类导入到views.py 模块中时遇到错误。 这是我的项目结构:
我在 Windows 10 上使用 Python 3.6。我在同一目录中有 2 个 .py 文件,char.py 和 char_user.py,如下所示: 字符.py: # char.py impor
import pickle class NoClass(): def __init__(self, name, level, cls, time_played): self.n
您好,我想测试我的可执行模块 main.py。在这个模块中有一个函数 main() 有两个参数: # main.py def main(population_size: int, number_of_
这在Python中合法吗?似乎有效... 谢谢 # with these lines you not need global variables anymore if __name__ == '__m
假设我们执行script_1。因此,script_1 是 __main__。但是,script_1 从 script_2 导入一些类。有没有办法,当我们输入 script_2 保存旧的 __main_
有没有这样的情况: import __main__ 可能会导致 ImportError?我尝试过的所有案例似乎都表明这总是有效的。 __main__ 上的文档似乎没有对此事发表任何看法。 为了提供一些
这个问题在这里已经有了答案: How to make __name__ == '__main__' when running module (4 个答案) 关闭 6 年前。 我有一个 python
我想通过测试确保:- 应用程序无法导入- 该应用程序可以作为真实应用程序启动(即:python src.py) 我对此很感兴趣,为什么以下不起作用: src.py class A: def x(se
我刚刚开始学习 Python,有一件事情困扰着我,那就是 "__main__" 的确切类型。到目前为止,我已经看到 "__main__" 主要用作字符串文字,如 __name__ == "__main
我有一个模块有通常的 if __name__ == '__main__': do stuff... 成语。 我想从另一个模块导入它,然后让它运行该代码。有什么办法吗? 我应该提一下,由于我不会
在Python,我们经常会编写 ? 1
我有这个 python 代码,我想从 Windows 运行中运行它。但是,当我尝试运行它时,cmd 会显示此消息。 C:\Users\myName\AppData\Local\Programs\Pyt
我无法在 python (2.7) 中正确命名子记录器。我有以下文件结构: -mypackage -__init__.py -main.py -log -__init__.py
当我尝试运行我的代码时出现此错误:\AppData\Local\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra
我是一名优秀的程序员,十分优秀!