在阅读fastapi的源代码时,这一行让我很模糊:
from starlette.testclient import TestClient as TestClient
Run Code Online (Sandbox Code Playgroud)
为什么不只是:from starlette.testclient import TestClient?
met*_*ter 14
从可执行代码的角度来看,两个不同的代码示例(使用Python 3.9)生成的Python字节码绝对没有区别:
>>> dis.dis('from starlette.testclient import TestClient as TestClient')
1 0 LOAD_CONST 0 (0)
2 LOAD_CONST 1 (('TestClient',))
4 IMPORT_NAME 0 (starlette.testclient)
6 IMPORT_FROM 1 (TestClient)
8 STORE_NAME 1 (TestClient)
10 POP_TOP
12 LOAD_CONST 2 (None)
14 RETURN_VALUE
>>> dis.dis('from starlette.testclient import TestClient')
1 0 LOAD_CONST 0 (0)
2 LOAD_CONST 1 (('TestClient',))
4 IMPORT_NAME 0 (starlette.testclient)
6 IMPORT_FROM 1 (TestClient)
8 STORE_NAME 1 (TestClient)
10 POP_TOP
12 LOAD_CONST 2 (None)
14 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
然而,Graham501617 的评论指出了现代类型提示验证器(例如mypy)如何接受这种特定语法来表示该导入名称的重新导出(另一个是__all__,值得庆幸的是,它们最终确实正确支持,因为这是一个标准自 Python 2 以来表示要(重新)导出的符号的语法。具体来说,根据引用的 PEP 0484 中存根文件的描述,引用:
- 导入到存根中的模块和变量不被视为从存根导出,除非导入使用该
import ... as ...形式或等效from ... import ... as ...形式。(更新:澄清一下,这里的目的是仅导出使用表单导入的名称X as X,即前后的名称as必须相同。)
TestClient这意味着该库可能遵循该特定约定,以方便从问题中引用的存根(模块)文件中重新导出名称。事实上,git blame在包中查找相关文件指向此提交(直接链接到文件的相关差异),该提交引用了此问题,其中包含类似的简短讨论以解决确切的类型提示问题;这样做是为了确保 mypy 将这些导入的名称视为重新导出,从而允许使用该--no-implicit-reexport标志(--strict可能已隐式启用)。
| 归档时间: |
|
| 查看次数: |
337 次 |
| 最近记录: |