RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 569357
Accepted
vitidev
vitidev
Asked:2020-09-23 06:54:45 +0000 UTC2020-09-23 06:54:45 +0000 UTC 2020-09-23 06:54:45 +0000 UTC

python中的隐式导入

  • 772

我无法弄清楚导入系统。为什么当我这样做时:

import os.path

然后我可以访问os.walk,它位于os,虽然我没有明确导入os?出于某种原因,这样的假动作不适用于它的package 。这是由于什么原因造成的?

更新

我知道 import 将导入的内容带入模块的命名空间。所以定义模块'myutils.py'c

import requests

在另一个模块中,得到如下图

import myutils
resp=myutils.requests.get('http://ya.ru') # работает
resp2=requests.get('http://ya.ru') #  NameError: name 'requests' is not defined

os.path 中的 import os 机制是否有一些特殊性?我知道 os.path 是 os 的一部分,而不是 2 个完全独立的包,但我想确切地了解该机制。

python
  • 3 3 个回答
  • 10 Views

3 个回答

  • Voted
  1. Best Answer
    jfs
    2020-09-23T20:46:37Z2020-09-23T20:46:37Z

    在 Python 中导入结合了两个操作:

    1. 查找(加载和初始化)模块
    2. 在当前环境中输入新名称(作为赋值运算符=)

    在搜索阶段(第 1 项)- 从规范-import构造:

    此名称将用于导入搜索的各个阶段,它可能是子模块的点路径,例如foo.bar.baz. 在这种情况下,Python 首先尝试导入foo,然后foo.bar是 ,最后 是foo.bar.baz。如果任何中间导入失败,ImportError 则会引发 an 。

    也就是说,import a.b.c导入 modules a, a.b,a.b.c如果上述任何模块导入失败,则无法成功导入更嵌套的模块。

    在命名阶段(第 2 项):

    如果被导入的模块不是顶级模块,那么包含该模块的顶级包的名称将绑定在本地命名空间中作为对顶级包的引用。必须使用其完整限定名而不是直接访问导入的模块

    import a.b.c在 Python 中,使a当前命名空间中的名称可用(例如,导入模块的全局命名空间a.b.c)并将属性:a.b和属性属性:分配a.b.c给适当的加载模块(类似于:a = sys.modules['a'];; a.b = sys.modules['a.b']..)。

    尽管这个问题很棘手,因为它os不是 Python 包(__path__属性未设置)并且os.path是普通属性(与 相同os.walk),不同之处在于它os.path是一个模块并且os.py包含 hack:(sys.modules['os.path'] = path允许import os.path构造)。import os本身已经可以os.path在没有import os.path.


    使用更常规的示例改写问题:

    为什么当我这样做时:即使我没有明确导入os , 我也可以访问os.walk,它位于os中?import os.pathimport html.parser html.escapehtml html

    import html.parser导入html和 (自然地)html.parser模块,并且由于html/__init__.py(在导入步骤中执行html)定义escape了一个函数,它html.escape()也可以像我们刚刚执行的那样使用import html。

    出于某种原因,这样的假动作不适用于它的包。这是由于什么原因造成的?

    如果module.nameafterimport module不起作用,那么这意味着您module/__init__.py没有定义name.

    旁白:性能module.name不依赖于__all__. __all__公开名称的文档(正式名称可由 访问from module import *)以避免在不属于接口的每个名称前加上_(默认情况下类型名称从 中_name排除from module import *)。但这并不禁止显式引用如module._name(这应该避免,但如果你真的想要,你可以)。旁白:不要from module import *在 REPL 之外或__init__.py文件之外使用(合理使用示例:asyncio/__init__.py-asyncio提供“平面”公共接口(名称可直接用作asyncio.name),尽管实现分布在许多嵌套模块中) .

    • 4
  2. Nikmoon
    2020-09-26T10:04:38Z2020-09-26T10:04:38Z

    只有显式导入才能导入mypackage.mymodule_XXX和使用。mypackage.mymodule_YYY__init__.pymymodule_YYY

    假设您有一个包裹mypackage:

    `/mypackage/`
        __init__.py
        mymodule_XXX.py
        mymodule_YYY.py
    

    __init__.py:

    from . import mymodule_XXX
    from . import mymodule_YYY
    

    然后你可以在你的程序中做你想做的事:

    import mypackage.mymodule_XXX
    
    # здесь можно смело использовать mypackage.mymodule_YYY
    print(mypackage.mymodule_YYY)
    

    至于myutils。当您导入一个模块时,您只是将一个变量引入程序的命名空间,而不是引入一个myutils变量,因此它没有被定义是合乎逻辑的。requests一个变量myutils,它是一个模块,有自己的命名空间,有一个变量requests,所以myutils.requests你可以通过它访问它。

    • 0
  3. vadim vaduxa
    2020-09-23T19:36:02Z2020-09-23T19:36:02Z
    print(len(globals()), globals().keys())
    import os.path
    print(len(globals()), globals().keys())
    

    当您导入 os.path 时,实际上导入了 os,显然 os 只是请求路径属性,这些导入不再发生

    8 dict_keys(['__name__', '__doc__', '__package__', '__cached__', '__spec__', '__builtins__', '__loader__', '__file__'])
    9 dict_keys(['__name__', '__doc__', '__package__', '__cached__', '__spec__', 'os', '__builtins__', '__loader__', '__file__'])
    

    从 os 导入路径将是正确的

    • -1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何停止编写糟糕的代码?

    • 3 个回答
  • Marko Smith

    onCreateView 方法重构

    • 1 个回答
  • Marko Smith

    通用还是非通用

    • 2 个回答
  • Marko Smith

    如何访问 jQuery 中的列

    • 1 个回答
  • Marko Smith

    *.tga 文件的组重命名(3620 个)

    • 1 个回答
  • Marko Smith

    内存分配列表C#

    • 1 个回答
  • Marko Smith

    常规赛适度贪婪

    • 1 个回答
  • Marko Smith

    如何制作自己的自动完成/自动更正?

    • 1 个回答
  • Marko Smith

    选择斐波那契数列

    • 2 个回答
  • Marko Smith

    所有 API 版本中的通用权限代码

    • 2 个回答
  • Martin Hope
    jfs *(星号)和 ** 双星号在 Python 中是什么意思? 2020-11-23 05:07:40 +0000 UTC
  • Martin Hope
    hwak 哪个孩子调用了父母的静态方法?还是不可能完成的任务? 2020-11-18 16:30:55 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    Arch ArrayList 与 LinkedList 的区别? 2020-09-20 02:42:49 +0000 UTC
  • Martin Hope
    iluxa1810 哪个更正确使用:if () 或 try-catch? 2020-08-23 18:56:13 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5