当前位置:网站首页>第10章 模块和包
第10章 模块和包
2022-08-04 11:53:00 【MallocLu】
文章目录
简介
- 包:将 多个功能模块 放在 一个包含__init__.py的文件夹里 , 对 不同功能的模块 进行分组管理。包可以嵌套定义。
- 模块:一个封装 具有相似功能的多个函数 的Python文件。
(在PyCharm中,创建普通文件夹并在其中创建__init__.py,普通文件夹将自动转换标记为package,和直接创建package结果相同)
导入
# from和import之后...代表 包名/模块名/属性名/方法名/类名
# as之后...代表 别名
import ...
import ... as ...
from ... import ...
from ... import ... as ...
导入包后,python解释器会找到包并执行其中的部分代码。在sys.path中可以看到python解释器会查找的路径。若导入包后提示没有找到包或包不存在,可以执行其中一个操作:1)将包放在正确的位置;2)告诉解释器到哪里去找包;
方便理解,这里举一个例子:
phello: 包
__init__.py 创建包时的默认文件
mhello.py 模块
# mhello.py
def printHello():
print('Hello World!')
1)将包放在正确的位置
sys.path包含一个目录列表,解释器将在这些目录中查找包。
其中较常用的为“site-packages目录”和“当前项目目录”。其中site-packages为默认的包安装位置,pip install和conda install的包都将存放在site-packages目录下;当前项目目录指的是用户个人正在编写的项目位置,在PyCharm中创建的包一般放在当前项目目录(或更下级目录)中,简单直观,方便编写和调试。
site-packages目录:不要放置单个py文件(例如mhello.py),而是放置包含py文件的包/文件夹(例如phello)
当前项目目录:可以放置单个py文件(例如mhello.py)
# 打印sys.path内容查看搜索路径
# windows
>>> import sys
>>> print(sys.path)
['E:\\PyCharm 2021.3\\plugins\\python\\helpers\\pydev',
'E:\\PyCharm 2021.3\\plugins\\python\\helpers\\pycharm_display',
'E:\\PyCharm 2021.3\\plugins\\python\\helpers\\third_party\\thriftpy',
'E:\\PyCharm 2021.3\\plugins\\python\\helpers\\pydev',
'E:\\anaconda\\envs\\py37tfcpu\\python37.zip',
'E:\\anaconda\\envs\\py37tfcpu\\DLLs',
'E:\\anaconda\\envs\\py37tfcpu\\lib',
'E:\\anaconda\\envs\\py37tfcpu',
# site-packages目录
'E:\\anaconda\\envs\\py37tfcpu\\lib\\site-packages',
'E:\\PyCharm 2021.3\\plugins\\python\\helpers\\pycharm_matplotlib_backend',
# 当前项目目录
'C:\\Users\\shang\\Desktop\\pythonProject',
'C:/Users/shang/Desktop/pythonProject']
# linux
>>> import sys
>>> print(sys.path)
[
# 当前项目目录
'',
'/root/miniconda3/envs/moviedeal/lib/python37.zip',
'/root/miniconda3/envs/moviedeal/lib/python3.7',
'/root/miniconda3/envs/moviedeal/lib/python3.7/lib-dynload',
# site-packages目录
'/root/miniconda3/envs/moviedeal/lib/python3.7/site-packages']
windows例:
# 将phello包放到main.py同级目录
# main.py
from phello.mhello import printHello
printHello()
# 将mhello.py模块放到main.py同级目录
# main.py
from mhello import printHello
printHello()
# 将phello包放到'E:\\anaconda\\envs\\py37tfcpu\\lib\\site-packages'目录中
# main.py
from phello.mhello import printHello
printHello()
linux例:
# 将phello包放到main.py同级目录
# main.py
from phello.mhello import printHello
printHello()
# 将mhello.py模块放到main.py同级目录
# main.py
from mhello import printHello
printHello()
# 将phello包放到'/root/miniconda3/envs/moviedeal/lib/python3.7/site-packages'目录中
# main.py
from phello.mhello import printHello
printHello()
2)告诉解释器到哪里去找
i)直接修改sys.path(不常见)
仅修改运行此次运行的sys.path
windows
# 将phello包放到main.py同级目录放在D盘根目录则sys.path.append('D:')
# 将phello包放到main.py同级目录放在D:/pkg录则sys.path.append('D:/pkg')
# main.py
import sys
sys.path.append('D:/pkg')
from phello.mhello import printHello
printHello()
linux
将phello包放到’~'目录下
不能直接将’‘添加到sys.path的末尾,必须使用完整的路径(例如’/home/yourusername’)或自动创建完整的路径(os.path.expanduser(''))
# main.py
import sys
sys.path.append('/home/yourusername')
from phello.mhello import printHello
printHello()
# main.py
import sys
import os
sys.path.append(os.path.expanduser('~'))
from phello.mhello import printHello
printHello()
ii)添加环境变量(标准做法)
关于环境变量详细参考:windows和linux的环境变量
pycharm会占用PYTHONPATH变量,使得在系统中配置的PYTHONPATH失效,所以分为使用cmd和使用pycharm运行main.py
windows
将phello包放到’D:\pkg’目录下
使用cmd
添加环境变量
# main.py
from phello.mhello import printHello
printHello()
使用pycharm
在pycharm的解释器上添加临时环境变量
# main.py
from phello.mhello import printHello
printHello()
linux
将phello包放到’~'目录下
使用cmd
> vim ~/.bashrc
# 在后面插入一行
# export PYTHONPATH=$PYTHONPATH:~
> source ~/.bashrc
# 命令行执行,不要使用pycharm(pycharm会占用PYTHONPATH变量,使得在系统中配置的PYTHONPATH失效)
# main.py
from phello.mhello import printHello
printHello()
使用pycharm
同windows,在pycharm的解释器上添加临时环境变量
编写
模块
注意__all__的使用:__all__为 from … import * 后外部所能导入属性,方法、类等,直接使用"模块名.xxx"或导入时指定"属性,方法,类"则不受影响。即__all__内容为该模块的主观开放成员(属性、方法、类等),所谓主观开放即作者主观上允许其他人调用的,而不在__all__中的内容作者不希望其他人调用(但是python语言的机制不是强制的,直接使用"模块名.xxx"或导入时指定"属性,方法,类"仍然可以调用)。
- 新建py文件test.py
- 编写模块
# test.py
__all__=['t1', 'printHello']
t1 = 2
t2 = 3
def printHello():
print('Hello')
def printWorld():
print('world')
- 导入和调用测试
# 成功调用t1, t2, printHello, printWorld
import test
print(test.t1)
print(test.t2)
test.printHello()
test.printWorld()
# 2
# 3
# Hello
# world
# 成功调用t1, t2, printHello, printWorld
from test import t1, t2, printHello, printWorld
print(t1)
print(t2)
printHello()
printWorld()
# 2
# 3
# Hello
# world
# 成功调用t1, printHello
# t2, printWorld不存在
from test import *
print(t1)
printHello()
# 2
# Hello
包
# digithello.py
__all__ = ['hello1', 'hello2']
def hello1():
print('Hello 1')
def hello2():
print('Hello 2')
def selfhello3():
print('Self Hello 3')
# letterhello.py
__all__ = ['helloA', 'helloB']
def helloA():
print('Hello A')
def helloB():
print('Hello B')
def selfhelloC():
print('Self Hello C')
空init
# __init__.py为空
# main.py
from hello.digithello import *
from hello.letterhello import *
hello1()
hello2()
helloA()
helloB()
非空init
使用__init__.py的优点:
1) 在__init__.py按需批量import,可以简化调用该包时的import语句
2) 在__init__.py按需import 搭配 新的__all__,定义 综合包内各个模块的总主观开放成员
# __init__.py
# 模块名可以使用hello.xxx或.xxx,不能使用xxx
from hello.digithello import *
from hello.letterhello import selfhelloC
__all__ = []
# 此处只能使用xxx.__all__,不能使用.xxx.__all__或hello.xxx.__all__
__all__.extend(digithello.__all__)
__all__.append('selfhelloC')
# main.py
from hello import *
hello1()
hello2()
selfhelloC()
__,定义 综合包内各个模块的总主观开放**成员
# __init__.py
# 模块名可以使用hello.xxx或.xxx,不能使用xxx
from hello.digithello import *
from hello.letterhello import selfhelloC
__all__ = []
# 此处只能使用xxx.__all__,不能使用.xxx.__all__或hello.xxx.__all__
__all__.extend(digithello.__all__)
__all__.append('selfhelloC')
# main.py
from hello import *
hello1()
hello2()
selfhelloC()
边栏推荐
猜你喜欢
请 AI 画家弄了个 logo,网友热议:画得非常好,下次别画了!
终于有人把分布式机器学习讲明白了
ESP8266-Arduino编程实例-APDS-9930环境光和趋近感器驱动
技术分享| 融合调度系统中的电子围栏功能说明
ESP8266-Arduino编程实例-MQ3酒精传感器驱动
Leetcode brush questions - 543. Diameter of binary trees, 617. Merging binary trees (recursive solution)
ESP8266-Arduino编程实例-TSL2561亮度传感器驱动
【RISC-V】Trap和Exception
企业应当实施的5个云安全管理策略
数据库表列类型;DML_添加数据;DDL_修改,删除数据库表
随机推荐
#夏日挑战赛#OpenHarmony 给你的输入法加点彩—星球崛起
基于BiLSTM的回归预测方法
【VBox】解决复制VBox虚拟机后提示硬盘UUID 已经存在的问题
AI 助力双碳目标:让每一度电都是我们优化的
Flutter强大的下拉筛选菜单gzx_dropdown_menu
ESP8266-Arduino编程实例-MQ3酒精传感器驱动
涨姿势了!原来这才是多线程正确实现方式
活动报名:如何高效应对当下的实时场景需求?
动手学深度学习_LeNet
深度学习------pytorch实现划拳模型训练
知道创宇EDR系统实力通过中国信通院端点检测与响应产品能力评测
到底什么是JS原型
2022上半年各银行理财子公司深耕差异化发展,净值型产品数量增加
【地平线旭日X3派试用体验】从开机到点灯(第一节)
Disc burning steps
【飞控开发高级教程7】疯壳·开源编队无人机-编队飞行
多表查询
C#控制台退出前操作
企业应当实施的5个云安全管理策略
*W3C* 标准组织