Python 导入究竟是如何工作的? [英] How does Python importing exactly work?

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

问题描述

我有两种具体情况,我不明白 Python 中的导入是如何工作的:

I have two specific situations where I don't understand how importing works in Python:

第一种特殊情况:

当我在两个不同的 Python 脚本中导入同一个模块时,该模块不会被导入两次,对吧?Python第一次遇到就导入,第二次是检查模块是否已经导入,还是做拷贝?

When I import the same module in two different Python scripts, the module isn't imported twice, right? The first time Python encounters it, it is imported, and second time, does it check if the module has been imported, or does it make a copy?

第二种具体情况:

考虑以下名为 bla.py 的模块:

Consider the following module, called bla.py:

a = 10

然后,我们有 foo.py,一个导入 bla.py 的模块:

And then, we have foo.py, a module which imports bla.py:

from bla import *

def Stuff ():
    return a

之后,我们有一个名为 bar.py 的脚本,它由用户执行:

And after that, we have a script called bar.py, which gets executed by the user:

from foo import *
Stuff() #This should return 10 
a = 5
Stuff()

这里我不知道:Stuff() 返回 10 还是 5?

Here I don't know: Does Stuff() return 10 or 5?

推荐答案

第 1 部分

模块只加载一次,因此再次导入不会有性能损失.如果您确实希望再次加载/解析它,则必须reload() 模块.

The module is only loaded once, so there is no performance loss by importing it again. If you actually wanted it to be loaded/parsed again, you'd have to reload() the module.

首先检查的是sys.modules,之前导入的所有模块的缓存.[来源]

The first place checked is sys.modules, the cache of all modules that have been imported previously. [source]

<小时>

第 2 部分

from foo import *a 导入到本地作用域.当给 a 赋值时,它会被新的值替换——但是原始的 foo.a 变量没有被触及.

from foo import * imports a to the local scope. When assigning a value to a, it is replaced with the new value - but the original foo.a variable is not touched.

所以除非你import foo 并修改foo.a,否则两个调用都会返回相同的值.

So unless you import foo and modify foo.a, both calls will return the same value.

对于可变类型,例如列表或字典,它会有所不同,修改它确实会影响原始变量 - 但为其分配新值仍然不会修改 foo.whatever.

For a mutable type such as a list or dict it would be different, modifying it would indeed affect the original variable - but assigning a new value to it would still not modify foo.whatever.

如果您需要更详细的信息,请查看 http://docs.python.org/reference/executionmodel.html:

If you want some more detailed information, have a look at http://docs.python.org/reference/executionmodel.html:

以下构造绑定名称:函数的形式参数、导入语句、类和函数定义(这些在定义块中绑定类或函数名称)以及作为标识符的目标如果出现在赋值、for循环头、except子句头的第二个位置或with语句之后.

The following constructs bind names: formal parameters to functions, import statements, class and function definitions (these bind the class or function name in the defining block), and targets that are identifiers if occurring in an assignment, for loop header, in the second position of an except clause header or after as in a with statement.

两个粗体部分与您相关:首先,名称 a 在导入期间绑定到 foo.a 的值.然后,在执行a = 5 时,名称a 绑定到5.由于修改 list/dict 不会导致任何绑定,这些操作将修改原始的(bfoo.b 绑定到您操作的同一个对象).将新对象分配给 b 将再次成为绑定操作,从而将 bfoo.b 分开.

The two bold sections are the relevant ones for you: First the name a is bound to the value of foo.a during the import. Then, when doing a = 5, the name a is bound to 5. Since modifying a list/dict does not cause any binding, those operations would modify the original one (b and foo.b are bound to the same object on which you operate). Assigning a new object to b would be a binding operation again and thus separate b from foo.b.

还值得注意的是 import 语句到底做了什么:

It is also worth noting what exactly the import statement does:

  • import foo 将模块名称绑定到当前范围内的模块对象,因此如果您修改 foo.whatever,您将使用该模块中的名称 -任何修改/赋值都会影响模块中的变量.
  • from foo import bar 仅将给定的名称(即 foo 将保持未绑定)绑定到 foo - 所以 bar 上的操作就像之前解释的一样.
  • from foo import * 的行为与前一个类似,但它导入所有没有下划线前缀的全局名称.如果模块定义了 __all__,则仅导入此序列内的名称.
  • import foo binds the module name to the module object in the current scope, so if you modify foo.whatever, you will work with the name in that module - any modifications/assignments will affect the variable in the module.
  • from foo import bar binds the given name(s) only (i.e. foo will remain unbound) to the element with the same name in foo - so operations on bar behave like explained earlier.
  • from foo import * behaves like the previous one, but it imports all global names which are not prefixed with an underscore. If the module defines __all__ only names inside this sequence are imported.

第 3 部分(在您的问题中甚至不存在:p)

Part 3 (which doesn't even exist in your question :p)

python 文档非常好,而且通常很冗长 - 您可以在其中找到几乎所有可能的与语言相关的问题的答案.以下是一些有用的链接:

The python documentation is extremely good and usually verbose - you find answer on almost every possible language-related question in there. Here are some useful links:

  • http://docs.python.org/reference/datamodel.html (classes, properties, magic methods, etc.) ()
  • http://docs.python.org/reference/executionmodel.html (how variables work in python)
  • http://docs.python.org/reference/expressions.html
  • http://docs.python.org/reference/simple_stmts.html (statements such as import, yield)
  • http://docs.python.org/reference/compound_stmts.html (block statements such as for, try, with)

这篇关于Python 导入究竟是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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