Python导入机制 [英] Python import mechanics

查看:163
本文介绍了Python导入机制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个相关的Python'import'问题。他们很容易测试,但我想要的答案是语言定义的,而不是实现特定的,我也对风格/约会感兴趣,所以我在这里问。



1)



如果模块A导入模块B,而模块B导入模块C,可以在模块A中引用模块C而不显式导入?



如果我导入模块ABC ,是否导入模块A和AB?如果是这样,按照惯例更好地显式地 import A;进口A.B; import ABC

解决方案

你应该知道的第一件事是Python语言不是ISO标准。这和C / C ++有很大不同,它意味着没有正确的方式来定义一个语言行为 - CPython可能只是因为它是以这种方式编码的,而Jython可能会做另一种方式。



关于你的问题,记住导入一个模块是一个两部分操作:首先加载模块 - 如果它从来没有,例如如果它在sys.modules中不可用,那么一个名称将绑定到本地命名空间中的该模块。



因此:



1)是的,你可以通过提供正确的命名空间来引用你想要的任何模块,例如您必须执行



BCname =something



很少在Python程序中执行,并且可以被认为是坏的做法,因为它强制一个传递dep - 如果一些模块B实现被重构并且不再依赖于C,它应该继续提供C模块只是为了满足A deps。 / p>

当然,设置__ all __可以防止这种情况,一个好的做法是在所有模块中放置__ all __,然后导出 您想要真正公开的符号。



2)是和否。正在处理

  import abcd 


b $ b

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

  a.something 
absomething
abcsomething

但不能执行

  c.something 
b.something

我必须承认的使用也是很少见;我通常喜欢从模块导入的东西的方式到导入,一般你只是问你需要什么 - 这种嵌套在图书馆中不常见,也不是其用法是常见的。



很多时候都有外包,只是用于组织,它们包含类的模块。很可能上面的a,b,c只是包,而d是一个真正包含类,函数和其他对象的模块。所以正确的用法是:

 来自abcd import name1,name2,name3 



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


I have two related Python 'import' questions. They are easily testable, but I want answers that are language-defined and not implementation-specific, and I'm also interested in style/convention, so I'm asking here instead.

1)

If module A imports module B, and module B imports module C, can code in module A reference module C without an explicit import? If so, am I correct in assuming this is bad practice?

2)

If I import module A.B.C, does that import modules A and A.B as well? If so, is it by convention better to explicitly import A; import A.B; import A.B.C?

解决方案

The first thing you should know is that the Python language is NOT an ISO standard. This is rather different from C/C++, and it means that there's no "proper" way to define a language behaviour - CPython might do something just because it was coded that way, and Jython might do the other way round.

about your questions, remember that "importing" a module is a two-part operation: first the module is loaded - if it had never been, e.g. if it wasn't available in sys.modules, then a name is bound to that module in the local namespace.

hence:

1) Yes, you can reference whatever you want from module a by providing the proper namespace, e.g. you'll have to do something like

B.C.name = "something"

And I think this is very rarely done in Python programs and could be considered bad practice since it forces a "transitive dep" - if some module B implementation is refactored and doesn't depend on C anymore, it should continue offering the C module just for satisfying A deps.

Of course setting __ all __ can prevent this, and a good practice may be to put __ all __ in all your modules, and export just the symbols you want to be really public.

2) Yes and no. Doing

import a.b.c.d 

performs the first import phase (loading) on all modules, but the second just on a (and, recursively, in b with respect to c, etc) but all the modules in the chain must be referenced by full namespace; after such an import, you can do

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

but you can't do

c.something
b.something

I must admit that kind of usage is pretty rare as well; I generally prefer the "from module import something" way-to-import, and generally you just ask for what you need - such nesting is neither common in libraries, nor its usage is that common.

Many times there're "outer packages", just used for organization, which hold modules with classes. It's very likely that a, b, c above are just packages, and d is a module which truly holds classes, functions and other objects. So the proper usage would be:

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

I hope this satifies your curiosity.

这篇关于Python导入机制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆