python package

文章目录

  • python package
  • 引言
  • 包的创建
  • 包的导入
  • `__init__.py`
    • `__init__.py`的设计原则
    • 参考资料:

引言

前提知识:days10-python-modules&& namespace学习

我们已经学习了python 的模块知识,我们也知道了模块就是.py文件,那如果我们有很多模块呢,是将他们放在一个目录下?那如果模块名相互重复了我们要怎么解决冲突呢?还有这个多模块之间肯定会有名称重复呀(函数名重复、全局变量名重复、类名重复等问题),我们如何解决?

要解决上面的问题我们就要引入包:包允许使用点表示法对模块命名空间进行分层结构管理。它有助于避免模块间全局变量名之间的冲突,包也有助于避免模块名之间的冲突。

python package ,其实就是一个目录,用来管理模块的,不过这个目录与我们操作系统的文件夹有点小小的不一样,它 必须包含__init__.py 这样一个模块(文件),这个文件的内容可以为空,但必须有这个文件来标识当前所在文件夹为python package。

包的创建

  • 直接通过创建文件夹的方式创建,并在文件夹中添加__init__.py 文件

通过这种方式创建,要注意你的文件夹所在路径一定要在sys.path的路径中呀。否则导入包的时候会提示找不到包哦。

  • 通过pycharm的方式创建。

举例:

我通过pycharm的方式创建了名称为package的包,并在包中添加了mod1.pymod2.py的两个模块

mod1.py

def mod1_func():print('[mod1] mod1_func()')mode_var='我是模块1'

mod2.py

def mod2_func():print('[mod2] mod2_func()')mode_var='我是模块2'

包的导入

我们可以通过类似于点的方式(pakcage.mod1, package.mod2)来import我们包中的模块,语法其实与模块的导入语法类似。

回忆模块的导入语法:

import <module_name>[, <module_name> ...]

包的导入举例:

工程下新建days11.py

import package.mod1,package.mod2
print(package.mod1.mode_var)
print(package.mod2.mode_var)
package.mod1.mod1_func()
package.mod2.mod2_func()

输出:

我是模块1
我是模块2
[mod1] mod1_func()
[mod2] mod2_func()

当然上面两种方式导致我们使用包中内容十分麻烦,我们要通过包名.模块名.这样的前缀去使用我们模块中的内容,我们改成from import的语句

回忆模块的from import语法:

from <module_name> import <name> as <alt_name>

举例:

from package.mod1 import mode_var as mode1_var ,mod1_func
from package.mod2 import mode_var as mode2_var,mod2_func
print(mode1_var)
print(mode2_var)
mod1_func()
mod2_func()

包也支持下面这种from import语法

from <package_name> import <modules_name>[, <module_name> ...]
from <package_name> import <module_name> as <alt_name>

示例:

from package import mod1 as model1
from package import mod2print(model1.mode_var)
print(mod2.mode_var)
model1.mod1_func()
mod2.mod2_func()

__init__.py

结论:该文件的作用就是相当于把自身整个文件夹当作一个包来管理,每当有外部import包或者包中模块的时候,就会自动执行里面的函数。

我们已经知道我们在模块中我们可以使用from <module_name> import *,[虽然不建议这样做]。那包是否也有个from <package_name> import *的语法呢?

试试:

我们知道dir()是返回当前命名空间的名称列表

列如:

from package.mod1 import *
print(dir())

输出:

[‘annotations’, ‘builtins’, ‘cached’, ‘doc’, ‘file’, ‘loader’, ‘name’, ‘package’, ‘spec’, ‘mod1_func’, ‘mode_var’]

结果是返回了mod1的内容呀

那么:

from package import *
print(dir())

是会返回package下的mod1、mod2名,还是?

结果:

['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']

无报错说明语法是支持的呀,但关于mod1、mod2什么也没有返回呀。实际上python遵循这样的约定:当我们使用from <package_name> import *这样的语句的时候,我们必须在__init__.py中在一个叫__all__名字的列表中列入你要导入的模块名

举例:

from package import *
print(dir())
mod1.mod1_func()
mod2.mod2_func()

结果:

其实模块中使用import * 也必须在模块中在__all__列表中申明什么要导入

__init__.py还可以干些什么呢?

举例我有如下的这种包结构

.
└── package
|    ├── subpackage
|    │   ├── mod3.py
|    │   └── subsonpackage
|    │       |__mod4.py
|    └── mod1.py
|    |__ mod2.py
|    |__ __init__.py
|_____ days11.py

模块对应代码如下

#mod1.py
def mod1_func():print('[mod1] mod1_func()')mode_var='我是模块1'#mod2.py
def mod2_func():print('[mod2] mod2_func()')mode_var='我是模块2'
#mod3.py
def mod3_func():print('[mod3] mod4_func()')mode_var='我是模块3'
##mod4.py
def mod4_func():print('[mod4] mod4_func()')mode_var='我是模块4'

试想我要在去days11.py引用mod1、mod2、mod3、mod4中的函数 ,那我是不是我要写类似下面这种的import 语句, 那如果我不止days10.py要引入,我还有其他文件都要引入,那是不是我每个文件都要写类似下面的这种import语句。

from package.subpackage.subsonpackage import mod4
from package.subpackage import mod3
from package import  mod1 , mod2

还有其他办法吗?不想写这么多重复的代码…

尝试一:

我啥都不干,直接导入包是否可行?

不行呀,显然它把我的包当成了模块来处理了…

尝试二 使用__init__.py

修改__init__.py文件,将我的导包语句放到__init__.py中呢

__init__.py

from package import mod1,mod2
from package.subpackage import mod3
from package.subpackage.subsonpackage import mod4

days11.py


import package as pgpg.mod1.mod1_func()
pg.mod2.mod2_func()
pg.mod3.mod3_func()
pg.mod4.mod4_func()

输出:

结果可行啊…

我甚至可以这样玩

__init__.py

from package import mod1,mod2
from package.subpackage import mod3
from package.subpackage.subsonpackage import mod4
func1=mod1.mod1_func
func2=mod2.mod2_func
func3=mod3.mod3_func
func4=mod4.mod4_func

days11.py

import package as pgpg.func1()
pg.func2()
pg.func3()
pg.func4()

输出:

什么原理?

答: 命名空间 ,在__init__.py中声明的所有类型和变量,就是其代表的模块的类型和变量。

__init__.py的设计原则

A、不要污染现有的命名空间。模块一个目的,是为了避免命名冲突,如果你在种用__init__.py时违背这个原则,是反其道而为之,就没有必要使用模块了。

B、利用__init__.py对外提供类型、变量和接口,对用户隐藏各个子模块的实现。

C、只在__init__.py中导入有必要的内容,不要做没必要的运算。


参考资料:

Python Modules and Packages – An Introduction

init__.py的神奇用法

python package学习相关推荐

  1. 【Python】Python语言学习:pip工具使用知识,模型保存pickle,PDF与docx相互转换处理...

    2022年第01周. 这一周的Python语言学习,记录如下. 01 pip工具使用知识 1 pip是什么? pip是一个用Python写的用于安装和管理包的包管理系统.它连接一个叫做Python P ...

  2. Spark集群,多个版本Python/Python Package管理

    文章转载自:http://blog.csdn.net/gongbi917/article/details/52369025 仅用于个人学习备忘收藏,转载请注明原文地址 进年来,越来越多的数据科学家.分 ...

  3. Python基础学习笔记之(二)

    Python基础学习笔记之(二) zouxy09@qq.com http://blog.csdn.net/zouxy09 六.包与模块 1.模块module Python中每一个.py脚本定义一个模块 ...

  4. Python基础学习笔记之(一)

    Python基础学习笔记之(一) zouxy09@qq.com http://blog.csdn.net/zouxy09 前段时间参加微软的windows Azure云计算的一个小培训,其中Pytho ...

  5. Time Series FeatuRe Extraction on basis of Scalable Hypothesis tests (tsfresh –A Python package)

    [目的]简单记录文献阅读过程,学习 tsfresh 库的相关SCI文章,希望可以减轻相关兴趣者的阅读与学习时间. [注意]翻译过程更多的为机器翻译和直译,有错误之处敬请斧正. Abstract: Ti ...

  6. Python深度学习-快速指南

    Python深度学习-快速指南 (Python Deep Learning - Quick Guide) Python深度学习-简介 (Python Deep Learning - Introduct ...

  7. python package打包制作

    python package打包制作 1. python package层次结构 2. python package打包,分发与安装 1. python package层次结构 根据navdeep-G ...

  8. Python课程学习笔记 下

    笔记目录 Python 学习笔记 上 面向对象和异常 面向对象 基本理论 定义类 根据类实例化对象 属性相关 方法相关 类的补充 属性补充 方法相关补充 描述器 python对象的生命周期 内存管理机 ...

  9. Python中的包(python package)

    主要是学习这句话: __init__.py 在包被导入时会被执行. 还有一些导入的细节. 当我们: 就会创建一个新的文件夹和文件夹下的 __init__.py 还会有个 · 所以,__init__.p ...

最新文章

  1. Windows 7 下IIS 7.5 结合Zend构建PHP集成开发环境
  2. 线切割机上的DOS系统
  3. 前后端分离中的权限管理思路
  4. 用Supermemo背单词达到8000词条
  5. linux服务器内存占用太高-释放内存
  6. 智能优化算法:材料生成优化算法-附代码
  7. 实习成长之路:MySQL十三: count(*)这么慢,我该怎么办?为什么那么慢?
  8. spnc币吧_CCIEC币-目前是CPUsolo独自开采。CPU服务器独自开采钱包上挖新币教程!...
  9. 优质的游戏音效推荐,不容错过
  10. c语言中until的用法,until的用法总结
  11. 2020年程序员年薪、婚恋、跳槽等报告出炉,说的是你吗?
  12. 十进制 -> N进制 写法 -- Java
  13. Laravel查询构造器的pluck方法第一个参数可选类型array的问题
  14. 学生成绩预测模型_2020年甘肃省建筑信息模型技术员(学生组)暨第三届全国装配式建筑职业技能竞赛(学生组)选拔赛成绩揭晓!...
  15. RiPro主题高级美化包支持最新版(附安装说明)
  16. Apache原理详解
  17. linux硬盘添加和挂载(linux硬盘的热插拔)
  18. CI/CD流水线技术方案
  19. 使用跟踪查看器查看 ASP.NET 跟踪信息
  20. 专转本-计算机二级习题1

热门文章

  1. 通用单口RJ45种类
  2. 【数据结构与算法】第一篇:数据结构
  3. 详细解说IMU惯性测量单元
  4. 软件工程 黄金点游戏
  5. 第三章 Dalvik 可执行格式与字节码规范
  6. 腾讯云mysql被黑_他被推下悬崖差点惨死,却意外得到MySQL的秘密......
  7. 课题一 认识数控机床
  8. 两周年软件开发工作有感
  9. caj文献放进zotero
  10. 八小时之内、八小时之外