栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

python包&模块

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python包&模块

引用资料:b站视频

【点击目录快速定位】

文章目录
  • 一、相关概念
    • 1.1、模块
    • 1.2、包/库
    • 1.3、框架
  • 二、包/模块的分类
    • 2.1、标准包/模块
    • 2.2、三方包/模块
    • 2.3、自定义包/模块
  • 三、包/模块的一般操作
    • 3.1、创建模块
    • 3.2、创建包
    • 3.3、包/模块的基本信息
    • 3.4导入包/模块
      • 3.4.1、常规导入
      • 3.4.2、from语句导入
      • 3.4.3、what happen when importing module?
      • 3.4.4、导入模块时的搜索路径
      • 3.4.5、导入模块的一些场景

一、相关概念 1.1、模块

一个.py文件,记录一组相关的功能,供其他py文件import使用。

1.2、包/库

把功能相关的模块和一个init.py放到一个文件夹里

1.3、框架

比较“好”的包/库,用框架就能写出质量好的项目。如Web开发使用的框架有Flask、Django…

二、包/模块的分类

python之所以强大,就是有很多库。

2.1、标准包/模块

安装python时自带的,满足基本需求,所有安装了python的电脑都能用这些模块。

1.需要import os、time…

2.不需要import builtins print()、list()、int()…

# python3 
import builtins
builtins.print("Hello world.")
print("Hello world.")	# 这两种写法都一样

# python2
import __builtin__
2.2、三方包/模块

别人写好的,需要下载。

2.3、自定义包/模块

自己写的。

三、包/模块的一般操作 3.1、创建模块

直接创建一个.py文件

3.2、创建包

新建一个文件夹,文件夹内创建__init__.py文件。(python2必须有、python3.3之后可以没有,但建议加上)

当import包之后,会先运行__init__.py文件。

3.3、包/模块的基本信息

包/模块的存放位置:print(xx.__file__)

查看包/模块里的内容:print(dir(xx))

3.4导入包/模块 3.4.1、常规导入

import M:导入单个模块,当M是某个包X里的模块时,应该写成 import X.M

import M1,M2导入多个模块

import M as 别名

引入别名除了能简化资源访问的前缀,还能增加程序的扩展性:

# 伪代码
if file_extension == "txt"
	import txt_p
    txt_p.open()
    txt_p.read()
    rxt_p.close()
elif file_extension =="doc"
	import doc_p
    doc_p.open()
    doc_p.read()
    doc_p.close()
————>
if file_extension == "txt"
	import txt_p as p
elif file_extension =="doc"
	import doc_p as p
p.open()
p.read()
p.close()

直接导入包名时,是不会导入包内的所有模块的。例如

dir1
  | -- __init__.py
  | -- mod_a.py
  | -- mod_b.py
----------demo.py---------------
import dir1
# 此时是无法直接调用 dir1.mod_a或dir1.mod_b的对象的。
----------demo.py---------------

解决方案:1、按路径显示调用模块:import 包.模块

​ 2、在__init__.py文件中import想要的模块 from . import 包中的模块

​ 3、用from语句。

3.4.2、from语句导入

from A import B [as C]

​ 【注意】只能从包导入模块or从模块导入模块资源,不能从包导入模块资源,不能从大包看到子包的模块。

​ from X import Y.M (x)

​ from X.Y import M (√) 【保证import后面是极简的,没有’点语法’】

慎用——防止变量命名冲突

批量导入:from 模块 import *、from 包 import *

​ *指定什么内容由开发者通过__all__变量决定(若没有__all__,则指定为所有非下划线开头的资源),因此,使用者无需关心包/模块里哪些资源是有用的(有些模块资源只是辅助、中间变量等,并不是拿来直接用的),只要用就行了。

----------test.py----------
from mod_A import *		# 此时*就是模块mod_A里的num_1和name
---------------------------

----------mod_A------------
num_1 = 10
name = "Stephen"
tmp = 0
__all__ = ["num_1","name"]  # 注意__all__是列表,里面的元素是字符串
---------------------------

# from 包 import *
# 指定*的内容时,在包内的__init__.py文件里定义__all__指定模块即可
3.4.3、what happen when importing module?

第一次导入时:

​ 1、在所导的模块下的命名空间中执行所有代码;

​ 2、创建一个module对象,并将模块内所有的顶级变量以属性的形式绑定到该对象上;

​ 3、在import语句所处的命名空间引入第2步创建的module对象的变量名称。

第二次导入时:直接执行第3步。(1、2步创建的module对象放到sys.modules里了<详见3.4.4>)

----------test.py----------------- # (对象.属性)
import mod_a
# 1、在所导的模块下的命名空间中执行所有代码;
num1 = 99
mod_a.run() # 运行结果num1为1,而非99。
			# 因为run的其实是mod_a.num1
    
# 2、创建一个module对象,并将模块内所有的顶级变量以属性的形式绑定到该对象上;
print(mod_a) # 
print(id(mod_a)) # 1697804609600
print(type(mod_a)) # 
print(mod_a.__dict__) # 显示模块mod_a所有属性(不包括nums3)
					  # nums3不是mod_a的顶级变量
    
# 3、在import语句所处的命名空间引入第2步创建的module对象的变量名称。
def f():
    import mod_a
    # 正常使用mod_a对象
#不能使用mod_a对象
----------test.py-----------------

----------mod_a.py-----------------
num1 = 1
num2 = 2
def run():
    num3 = 3
    print("run")
    print(num1)
----------mod_a.py-----------------

用reload()重新装载模块:

​ 因为在主文件上import后模块会被记录下来,所以对原模块进行的更新不影响已运行过的主文件对模块的使用。python用reload方法来重新加载修改后的模块。

import mod_a
# …… 对mod_a修改了

from importlib import reload
reload(mod_a)

了解即可。现在的 IDE 大都不需要我们这么做。

3.4.4、导入模块时的搜索路径

当我们import 模块 时,python按照什么顺序搜索所需的模块呢?

第一次导入:

(1) 先找内置的模块(built-in),再找sys.path里的路径的模块

(2) sys.path:(包括四部分)

​ ①当前目录下搜索

​ ②环境变量PYTHONPATH中指定的路径列表

​ ③特定路径下的.pth文件中指定的路径列表

​ ④在python安装路径的lib库中搜索

用print(sys.path)可以查看其包含的路径

<打印出来的是一个列表,因此是有序的,python在搜索模块时就是按照这个顺序搜索的>

(3) 如果想要import的模块不在sys.path里面,可以追加进去,就能import了。

​ 追加路径的方式:(详情观看视频)

第二次导入:

从已加载过的模块去找

可以用sys.modules查看已加载过的模块

综上:导入一个模块时,python底层的搜索顺序为sys.modules——>built-in——>sys.path

3.4.5、导入模块的一些场景

①局部导入

# 当只需要在func里用到Module_1的一部分资源时,
# 在内部import更好,可以节省时间。(物尽其用)
# 毕竟func函数也不一定被调用到。
def func():
    import Module_1
    # 这里使用Module_1的资源
    
# 若出了func函数的命名空间,
# 就无法使用Module_1的资源。

②覆盖导入

​ 1)自定义模块和非内置模块重名:按sys.path路径,优先级高的覆盖低的。

​ 2)自定义模块和内置模块重名:内置模块覆盖自定义模块。

(ps.用from语句指明绝对路径就能使用这里的自定义模块)

from 包名 import 模块

ps.应避免重名!

③循环导入

---------test.py---------------
t1 = 't1'
t2 = 't2'
import other 
print(other.o1)
print(other.o2)
---------test.py---------------
---------other.py--------------
o1 = 'o1'
o2 = 'o2'
import test
print(test.t1)
print(test.t2)
---------other.py--------------

通过3.4.3和3.4.4可以知道,两个文件互相导入,但不会像递归一样死循环,因为import的模块对象只创建一遍,不会再去执行第二遍。

④可选导入

# 优先导入other_1,如果other_1不存在
# 则导入other_2
try:
    import other_1 as o
except ModuleNotFoundError:
    import other_2 as o
# 【注意】1.两个模块都要起一个一样的别名,道理很简单。
# 		2.两个模块应该除实现逻辑外,其他属性名、方法名
#		  都相同,否则调用时候就出错了。

⑤包内导入

包内导入的方式:

​ 绝对导入:指定包名和模块名。from 包名 import 模块名

​ 相对导入:from . import 模块名 和 from .. import 模块名

如果一个py文件以脚本的形式执行python file,它的名称就是__main__ (print(__name__))

如果一个py文件是被以模块的形式加载的,它的名称由加载路径决定,一般是:包名.子包名.模块名

比如package_2.package_1.module_A,此时package_2叫做【顶级名称】

【注意】对python2而言,包内导入时,import 模块 属于隐式相对导入,即和from . import 模块 作用是一样的,若想和python3一样是绝对导入,需在前面加上from __future__ import absolute_import。

总结:
包内导入:使用相对导入
​ 包外导入:使用绝对导入

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/931775.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号