python import和from xx import xx的理解

本文深入解析Python中的import和from...import语句的工作原理,通过实例对比两种导入方式的区别,包括它们如何影响当前名称空间,以及在循环导入时的行为。特别强调了在Flask框架下,不使用Blueprint进行文件分离时可能遇到的问题。

先挂标准解释

引用地址–>http://effbot.org/zone/import-confusion.htm

原文

import X imports the module X, and creates a reference to that module in the current namespace. Or in other words, after you’ve run this statement, you can use X.name to refer to things defined in module X.

from X import * imports the module X, and creates references in the current namespace to all public objects defined by that module (that is, everything that doesn’t have a name starting with “_”). Or in other words, after you’ve run this statement, you can simply use a plain name to refer to things defined in module X. But X itself is not defined, so X.name doesn’t work. And if name was already defined, it is replaced by the new version. And if name in X is changed to point to some other object, your module won’t notice.

from X import a, b, c imports the module X, and creates references in the current namespace to the given objects. Or in other words, you can now use a and b and c in your program.

Finally, X = import(‘X’) works like import X, with the difference that you 1) pass the module name as a string, and 2) explicitly assign it to a variable in your current namespace.

翻译(google)

import X导入模块X,并在当前名称空间中创建对该模块的引用。换句话说,运行此语句后,可以使用X.name引用模块X中定义的内容。

from X import *导入模块X,并在当前名称空间中创建对该模块定义的所有公共对象的引用(即,所有不具有以“ _”开头的名称的对象)。换句话说,运行该语句后,您可以简单地使用一个简单的名称来引用模块X中定义的内容。但是X本身未定义,因此 X.name不起作用。如果已经定义了名称,则将其替换为新版本。而且,如果将X中的名称更改为指向其他对象,则您的模块将不会注意到。

from X import a, b, c导入模块X,并在当前名称空间中创建对给定对象的引用。换句话说,您现在可以在程序中使用a,b和c。

最后,X = __import __(‘X’)的作用类似于import X,不同之处在于您1)将模块名称作为字符串传递,以及2)将其显式分配给当前名称空间中的变量。

主要讨论import 和 from import

通俗理解

例:import time
直接import 导入, 开辟内存空间time, 将time模块下的代码读入内存, 例: sleep, 通过time.sleep()使用, 简单来说就是当前运行就只有一个time变量

例: from time import sleep
在当前工作空间创建sleep变量, 直接sleep()使用, 所有容易被覆盖

不讲概念了, 直接案例

先使用import

-----新建a.py------------------------------------------------------------------------------------------

example = {'a': 0}
# 主要关注import b
import b

if __name__ == "__main__":
    print(example)
    print(b.example)

-----新建b.py------------------------------------------------------------------------------------------

from a import example

example['b'] = 0

运行a.py后打印

{'a': 0}
{'a': 0, 'b': 0}

解释:
从上往下依次理解
新建example = {‘a’: 0}
import b: 运行b.py到from a import example:
又重新执行一个a.py到example(!!!注意这里的example是另外一个了),
接着example[‘b’] = 0, 执行完b.py回到a.py打印第一个example, 这个很好理解,
接着一个b.example是因为重新执行一个a.py中获取到example = {‘a’: 0}在执行example[‘b’] = 0
所以最后打印结果

接着from import

-----新建a.py------------------------------------------------------------------------------------------

example = {'a': 0}
# 主要关注from b import *
from b improt *

if __name__ == "__main__":
    print(example)

-----新建b.py------------------------------------------------------------------------------------------

from a import example

example['b'] = 0

运行a.py后打印

{'a': 0, 'b': 0}

解释:
从上往下依次理解
新建example = {‘a’: 0}
from b improt *: 运行b.py,
from a import example
example[‘b’] = 0
将b中变量都在a中创建一个, 这时候b中第二个example就会覆盖掉a中example
所以最后打印结果

{'a': 0, 'b': 0}

在flask中不使用blueprint, 又想分文件, 所以遇到改问题

最后理解

原文:https://www.jianshu.com/p/a2cbf2bddf83
在Python中,导入并不是把一个文件文本插入另一个文件中。导入其实是运行时的运算,程序第一次导入指定文件时,会执行三个步骤。
1、搜索找到模块文件。
2、编译成字节码(需要时)。
3、执行模块的代码来创建其所定义的对象,定义 import 语句所在文件的作用域的局部命名空间中的一个或多个变量名。

这三个步骤只在模块第一次导入时才会执行。在这之后,导入相同模块时,会跳过这三个步骤,而只是提取内存中已加载的模块对象。这是有意而为之的,因为该操作开销较大。如果你在模块已加载后还需要再次导入(例如,为了支持终端用户的定制),你就得通过调用 reload() 强制导入模块。

从技术上讲,Python 把载入的模块存储到一个名为 sys.modules 的表中,并在导入操作的开始检查该表。如果模块不存在,将会自动执行上面的三个步骤。

看完后理解了为何在循环导入有疑问时, 在运行文件和模块文件都加入print语句运行文件会执行两次, 而模块文件却不会, 是因为运行是没有当做导入的, 所以不会存在导入模块表中, 然后当模块文件重新导入运行文件时, 这时候运行文件就被当做模块文件导入了, 所以运行文件经常被加载两次, 而模块文件之后加载一次, 之后的导入都是去模块文件加载内存中去取变量

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值