0、_init_.py

在Python工程里,当python检测到一个目录下存在_init_.py文件时,python就会把它当成一个模块(module)。Module跟C++的命名空间和Java的Package的概念很像,都是为了科学地组织化工程,管理命名空间。

__init__.py可以是一个空文件,也可以有非常丰富的内容。本文将举一个非常简单的例子,来介绍__init__.py的用法;在本文的最后,我将会再简单介绍_init_.py的设计理念。

1、一个普通的四则运算模块

在不利用_init_.py的情况下,我们来看一个四则运算的例子。我们的工程目录结构如下图所示:

每个文件的代码如下:

# @file main.py

import arithmetic.add
import arithmetic.sub as sub from arithmetic.mul import mul
from arithmetic import dev def letscook(x, y, op):
r = 0
if op == '+':
r = arithmetic.add.add(x, y)
elif op == '-':
r = sub.sub(x, y)
elif op == '*':
r = mul(x, y)
else:
r = dev.dev(x, y) print("{} {} {} = {}".format(x, op, y, r)) x, y = 3, 8
letscook(x, y, "+")
letscook(x, y, "-")
letscook(x, y, "*")
letscook(x, y, "/")
# @file add.py

def add(a, b):
return a + b
# @file sub.py

def sub(a, b):
return a - b
# @file mul.py

def mul(a, b):
return a * b
# @file dev.py

def dev(a, b):
return a / b

从代码可以看出,为了使用 arithmetic 中的某个子模块( main.py中我们展示了四种不同的方式),我们必须使用非常繁琐的 import 语句;在使用的时候,也有可能需要使用非常繁琐的表达式。如果我们在不同的地方使用 arithmetic 的子模块,都需要写这么繁琐的 import 或者使用表达式,你可能会觉得心累。这就是为什么我们需要利用 _init_.py 来简化我们的使用。

2、利用_init_.py

还是第 \(1\) 小节中的工程目录结构,实现同样的功能,我们在_init_.py中编写了一些代码;同样,我们对main.py进行了一些适当的修改。

修改后_init_.py和 main.py 的代码如下:

# @file __init__.py

import arithmetic.add
import arithmetic.sub
import arithmetic.mul
import arithmetic.dev add = arithmetic.add.add
sub = arithmetic.sub.sub
mul = arithmetic.mul.mul
dev = arithmetic.dev.dev
# @file main.py

import arithmetic as a4

def letscook(x, y, op):
r = 0
if op == "+":
r = a4.add(x, y)
elif op == "-":
r = a4.sub(x, y)
elif op == "*":
r = a4.mul(x, y)
else:
r = a4.dev(x, y) print("{} {} {} = {}".format(x, op, y, r)) x, y = 3, 8
letscook(x, y, "+")
letscook(x, y, "-")
letscook(x, y, "*")
letscook(x, y, "/")

在__init__.py中, 我们 importarithmetic 下的所有子模块,并在_init_.py中给各个子模块的核心功能取了新的名字,作为 arithmetic模块的变量。所以我们在 main.pyimportarithmetic 模块之后,就可以直接进行使用了。如果你使用 from arithmetic import * 语句,那么我们就可以使用 add、sub、mul、dev,连 a4都省了。

3、_init_.py的设计原则

__init__.py的原始使命是声明一个模块,所以它可以是一个空文件。在__init__.py中声明的所有类型和变量,就是其代表的模块的类型和变量,第2小节就是利用这个原理,为四则运算的4个子模块声明了新的变量。我们在利用_init_.py时,应该遵循如下几个原则:

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

B、利用_init_.py对外提供类型、变量和接口,对用户隐藏各个子模块的实现。一个模块的实现可能非常复杂,你需要用很多个文件,甚至很多子模块来实现,但用户可能只需要知道一个类型和接口。就像我们的arithmetic例子中,用户只需要知道四则运算有add、sub、mul、dev四个接口,却并不需要知道它们是怎么实现的,也不想去了解arithmetic中是如何组织各个子模块的。由于各个子模块的实现有可能非常复杂,而对外提供的类型和接口有可能非常的简单,我们就可以通过这个方式来对用户隐藏实现,同时提供非常方便的使用。

C、只在__init__.py中导入有必要的内容,不要做没必要的运算。像我们的例子,import arithmetic语句会执行__ini__.py中的所有代码。如果我们在__init__.py中做太多事情,每次import都会有额外的运算,会造成没有必要的开销。一句话,init.py只是为了达到B中所表述的目的,其它事情就不要做啦。

Python | __init__.py的神奇用法的更多相关文章

  1. python __init__.py用途

    转自http://www.cnpythoner.com/post/2.html Python中的Module是比较重要的概念.常见的情况是,事先写好一个.py文 件,在另一个文件中需要import时, ...

  2. python __init__.py

    python中的Module是比较重要的概念.常见的情况是,事先写好一个.py文 件,在另一个文件中需要import时,将事先写好的.py文件拷贝 到当前目录,或者是在sys.path中增加事先写好的 ...

  3. <转>Python: __init__.py 用法

    转自 http://www.cnblogs.com/BeginMan/p/3183629.html python的每个模块的包中,都有一个__init__.py文件,有了这个文件,我们才能导入这个目录 ...

  4. Python __init__.py 作用详解

    __init__.py 文件的作用是将文件夹变为一个Python模块,Python 中的每个模块的包中,都有__init__.py 文件. 通常__init__.py 文件为空,但是我们还可以为它增加 ...

  5. Python __init__.py文件的作用

    我们经常在python的模块目录中会看到 "__init__.py"  这个文件,那么它到底有什么作用呢? 1. 模块包(module package)标识 如果你是使用pytho ...

  6. python __init__.py 的作用

    __init__.py的主要作用是: . Python中package的标识,不能删除 . 定义__all__用来模糊导入 . 编写Python代码(不建议在__init__中写python模块,可以 ...

  7. Python __init__.py 文件使用

    __init__.py的主要作用是: 1. Python中package的标识,不能删除 2. 定义__all__用来模糊导入 3. 编写Python代码(不建议在__init__中写python模块 ...

  8. 【转】【Python】Python中的__init__.py与模块导入(from import 找不到模块的问题)

    python中的Module是比较重要的概念.常见的情况是,事先写好一个.py文 件,在另一个文件中需要import时,将事先写好的.py文件拷贝 到当前目录,或者是在sys.path中增加事先写好的 ...

  9. Python学习笔记之__init__.py文件的作用

    参考地址:http://www.cnblogs.com/Lands-ljk/p/5880483.html Python __init__.py 作用详解 __init__.py 文件的作用是将文件夹变 ...

  10. 转载 - Python里面关于 模块 和 包 和 __init__.py 的一些事

    出处:http://www.cnblogs.com/tqsummer/archive/2011/01/24/1943273.html python中的Module是比较重要的概念.常见的情况是,事先写 ...

随机推荐

  1. CSS(不定时更新)

    一.使用img后的高度多了4px 由于img是行内元素,默认display: inline; 它与文本的默认行为类似,下边缘是与基线(baseline)对齐,而不是紧贴容器下边缘. 将displayp ...

  2. 算法与数据结构——kpm算法

  3. Hudi 在 vivo 湖仓一体的落地实践

    作者:vivo 互联网大数据团队 - Xu Yu 在增效降本的大背景下,vivo大数据基础团队引入Hudi组件为公司业务部门湖仓加速的场景进行赋能.主要应用在流批同源.实时链路优化及宽表拼接等业务场景 ...

  4. 第一章 JavaEE应用和开发环境

    1.1 java EE应用概述 1.java EE的分层模型 数据库--[提供持久化服务]-->Domain Object层 --[封装]--〉DAO层--[提供数据访问服务]-->业务逻 ...

  5. The second day learning summary

    1.什么是接口测试? 接口测试是测试系统组件间接口的一种测试.接口测试主要用于外部系统与系统之间以及内部各个子系统之间的交互点,定义特定的交互点,然后通过这些交互点来,通过一些特殊的规则也就是协议,来 ...

  6. Python——Html(内联框架<iframe>)

    <iframe>(内联框架)是 HTML 中的一个标签,用于在当前文档中嵌入另一个文档.它提供了一种将一个 HTML 文档嵌套到另一个文档的方式,允许在一个页面中显示另一个页面的内容.以下 ...

  7. LLM增强LLM;通过预测上下文来提高文生图质量;Spikformer V2;同时执行刚性和非刚性编辑的通用图像编辑框架

    文章首发于公众号:机器感知 LLM增强LLM:通过预测上下文来提高文生图质量:Spikformer V2:同时执行刚性和非刚性编辑的通用图像编辑框架 LLM Augmented LLMs: Expan ...

  8. 玩转Python:数据可视化,一个很高级的交互式Python库,附代码

    在数据科学和分析的世界里,将数据可视化是至关重要的一步,它能帮助我们更好地理解数据,发现潜在的模式和关系.Python 提供了多种可视化工具,HvPlot 是其中一个出色的库,专为简单且高效的交互式可 ...

  9. table中td超出内容隐藏,鼠标悬停全部显示(完整版,含js代码)

    一.CSS语法: text-overflow:clip | ellipsis 默认值:clip 适用于:所有元素 clip: 当对象内文本溢出时不显示省略标记(...),而是将溢出的部分裁切掉. el ...

  10. 2023-06-04:你的音乐播放器里有 N 首不同的歌, 在旅途中,你的旅伴想要听 L 首歌(不一定不同,即,允许歌曲重复, 请你为她按如下规则创建一个播放列表, 每首歌至少播放一次, 一首歌只有在

    2023-06-04:你的音乐播放器里有 N 首不同的歌, 在旅途中,你的旅伴想要听 L 首歌(不一定不同,即,允许歌曲重复, 请你为她按如下规则创建一个播放列表, 每首歌至少播放一次, 一首歌只有在 ...