Python导入机制

发布于 2021-01-29 19:09:28

我有两个相关的Python“导入”问题。它们很容易测试,但是我想要的答案是语言定义的,而不是特定于实现的,而且我对样式/约定也很感兴趣,所以我在这里问。

1)

如果模块A导入模块B,模块B导入模块C,则模块A中的代码可以引用模块C而不进行显式导入吗?如果是这样,我是否认为这是错误的做法?

2)

如果导入模块ABC,那么是否也导入模块A和AB?如果是这样,按照惯例更好地进行显式表示import A; import A.B; import A.B.C吗?

关注者
0
被浏览
49
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    您应该知道的第一件事是Python语言不是ISO标准。这与C / C ++完全不同,这意味着没有“适当”的方法来定义语言行为-
    CPython可能会做某事,因为它是用这种方式编码的,而Jython可能会做另一回事。

    关于您的问题,请记住“导入”模块是一个分为两部分的操作:首先加载该模块-
    如果从未加载过该模块,例如,如果sys.modules中不提供该模块,则将名称绑定到该模块在本地名称空间中。

    因此:

    1)是的,您可以通过提供适当的名称空间来引用模块a中的任何内容,例如,您必须执行以下操作

    BCname =“某物”

    而且我认为这很少在Python程序中完成,并且可能会被认为是不好的做法,因为它会强制执行“传递性dep”-如果某些模块B的实现被重构并且不再依赖于C,它应该继续提供C模块为满足A部门。

    当然,设置__ all 可以避免这种情况,一个好的实践可能是将 all __放入所有模块中,并 导出要真正公开的符号。

    2)是和否。在做

    import a.b.c.d
    

    在所有模块上执行第 一个
    导入阶段(加载),但第二个阶段仅在a上执行(并且递归地,在b中相对于c等),但是链中的所有模块都必须由完整的命名空间引用;这样导入后,您可以

    a.something
    a.b.something
    a.b.c.something
    

    但是你做不到

    c.something
    b.something
    

    我必须承认这种用法也很罕见。我通常更喜欢“从模块中导入某些东西”的导入方式,并且通常您只是问自己需要什么-这种嵌套在库中既不常见,也不常见。

    很多时候,有用于组织的“外部软件包”,其中包含带有类的模块。上面的a,b,c很可能只是包,而d是真正包含类,函数和其他对象的模块。因此正确的用法是:

    from a.b.c.d import name1, name2, name3
    

    我希望这能满足您的好奇心。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看