为什么要使用`从模块导入a作为a的`而而不是从模块导入a'

发布于 2025-02-04 15:24:56 字数 225 浏览 2 评论 0 原文

在阅读FastApi的源代码时,这一行使我模糊:

from starlette.testclient import TestClient as TestClient

为什么不只是: from starlette.testclient Import Testclient

When reading source code of fastapi, this line make me fuzzy:

from starlette.testclient import TestClient as TestClient

Why not just: from starlette.testclient import TestClient?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

何以畏孤独 2025-02-11 15:24:56

从可执行代码的角度来看,两个不同的代码示例生成的python字节码(使用Python 3.9)绝对没有区别:

>>> 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

如图所示,它们完全相同。 (相关问题 存在 //peps.python.org/pep-0484/“ rel =“ nofollow noreferrer”> pep-0484 )。

但是, Graham501617的评论指出了现代类型的提示验证器(例如 mypy )接受此特定语法以表示该导入名称的重新出口(另一个是 ____________________ ,值得庆幸的是,他们最终确实得到了支持,因为这已经是如此,因为这已经是如此,因为这已经如此, a 标准语法以自Python 2 以来表示符号(re-)导出符号) 。具体而言,根据

  • 导入到存根的模块和变量不被视为从存根中导出,除非导入使用 import ... as ... 表单或来自...导入的等效。 .. AS ... 表格。 (更新:要澄清,此处的目的是仅使用 x作为x 导入的名称被导出,即 之前和之后的名称必须相同。 )

查看直接链接到文件的相关差异)表示正在解决此特定类型的提示问题(作为这个问题)以确保mypy将这些导入的名称视为re-Exexport ,从而允许使用 flag( - 严格 可能已隐式启用)。

然而,此特定的重新出口语法非常严格,对“ 的名称必须相同”,相关问题中引用的语法(即)可以在某些现代软件包的推荐中找到(例如,Pytorch建议使用导入Torch.nn作为NN ,如这个问题),实际上不允许 bar (或 nn )符号从当前模块重新出口为 foo.bar bar 不相同代码>(同样是 torch.nn nn 不同,因为将整个令牌 torch.nn 评估而不是仅仅是最终之后的最终标识符)。

From the point of view of executable code, there is absolutely no difference in terms of the Python bytecode being generated by the two different code examples (using Python 3.9):

>>> 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

As shown, they are exactly identical. (Related question asked before existence of PEP-0484).

However, the comment by Graham501617 noted how modern type hinting validators (such as mypy) accept this particular syntax to denote the re-export of that imported name (the other being the __all__, which thankfully they did end up correctly supporting as that has been a standard syntax to denote symbols to (re-)export since Python 2). Specifically, as per the description of Stub Files in the referenced PEP 0484, quote:

  • Modules and variables imported into the stub are not considered exported from the stub unless the import uses the import ... as ... form or the equivalent from ... import ... as ... form. (UPDATE: To clarify, the intention here is that only names imported using the form X as X will be exported, i.e. the name before and after as must be the same.)

Looking at git blame for the relevant file in the packages pointed to this commit (direct link to relevant diff for the file) indicated that this particular type hinting issue was being addressed (as part of this issue) to ensure mypy will treat those imported names as re-export, thus allowing the usage of the --no-implicit-reexport flag (which --strict has likely implicitly enabled).

This particular re-export syntax however is very much strict about the "name before and after as must be the same", the syntax referred in the related question (i.e. import foo.bar as bar) can be found in recommendation by certain modern packages (e.g. PyTorch recommends the use of import torch.nn as nn, as discussed in this question), does not in fact allow the bar (or nn) symbol be re-exported from the current module as foo.bar is not the same as bar (likewise torch.nn is not the same as nn, as the whole set of tokens torch.nn is evaluated instead of the just the final identifier after the final .).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文