出处:http://www.cnblogs.com/tqsummer/archive/2011/01/24/1943273.html

python中的Module是比较重要的概念。常见的情况是,事先写好一个.py文 件,在另一个文件中需要import时,将事先写好的.py文件拷贝 到当前目录,或者是在sys.path中增加事先写好的.py文件所在的目录,然后import。这样的做法,对于少数文件是可行的,但如果程序数目很 多,层级很复杂,就很吃力了。
有没有办法,像Java的Package一样,将多个.py文件组织起来,以便在外部统一调用,和在内部互相调用呢?答案是有的。
主要是用到python的包的概念,python __init__.py在包里起一个比较重要的作用
要弄明白这个问题,首先要知道,python在执行import语句时,到底进行了什么操作,按照python的文档,它执行了如下操作:
第1步,创建一个新的,空的module对象(它可能包含多个module);
第2步,把这个module对象插入sys.module中
第3步,装载module的代码(如果需要,首先必须编译)
第4步,执行新的module中对应的代码。

在执行第3步时,首先要找到module程序所在的位置,其原理为:
如 果需要导入的module的名字是m1,则解释器必须找到m1.py,它首先在当前目录查找,然后是在环境变量PYTHONPATH中查找。 PYTHONPATH可以视为系统的PATH变量一类的东西,其中包含若干个目录。如果PYTHONPATH没有设定,或者找不到m1.py,则继续搜索 与python的安装设置相关的默认路径,在Unix下,通常是/usr/local/lib/python。
事实上,搜索的顺序是:当前路径 (以及从当前目录指定的sys.path),然后是PYTHONPATH,然后是python的安装设置相关的默认路径。正因为存在这样的顺序,如果当前 路径或PYTHONPATH中存在与标准module同样的module,则会覆盖标准module。也就是说,如果当前目录下存在xml.py,那么执 行import xml时,导入的是当前目录下的module,而不是系统标准的xml。

了解了这些,我们就可以先构建一个package,以普通module的方式导入,就可以直接访问此package中的各个module了。

Python中的package定义很简单,其层次结构与程序所在目录的层次结构相同,这一点与Java类似,唯一不同的地方在于,python中的package必须包含一个__init__.py的文件。
例如,我们可以这样组织一个package:

package1/
    __init__.py
    subPack1/
        __init__.py
        module_11.py
        module_12.py
        module_13.py
    subPack2/
        __init__.py
        module_21.py
        module_22.py
    ……

__init__.py可以为空,只要它存在,就表明此目录应被作为一个package处理。当然,__init__.py中也可以设置相应的内容,下文详细介绍。

好了,现在我们在module_11.py中定义一个函数:

def funA():
    print "funcA in module_11"
    return

在顶层目录(也就是package1所在的目录,当然也参考上面的介绍,将package1放在解释器能够搜索到的地方)运行python:

>>>from package1.subPack1.module_11 import funcA
>>>funcA()
funcA in module_11

这样,我们就按照package的层次关系,正确调用了module_11中的函数。

细心的用户会发现,有时在import语句中会出现通配符*,导入某个module中的所有元素,这是怎么实现的呢?
答案就在__init__.py中。我们在subPack1的__init__.py文件中写

__all__ = ['module_13', 'module_12']

然后进入python

>>>from package1.subPack1 import *
>>>module_11.funcA()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named module_11

也就是说,以*导入时,package内的module是受__init__.py限制的。

好了,最后来看看,如何在package内部互相调用。
如果希望调用同一个package中的module,则直接import即可。也就是说,在module_12.py中,可以直接使用

import module_11

如果不在同一个package中,例如我们希望在module_21.py中调用module_11.py中的FuncA,则应该这样:

from module_11包名.module_11 import funcA

转载 - Python里面关于 模块 和 包 和 __init__.py 的一些事的更多相关文章

  1. Python类、模块、包的区别

    类 类的概念在许多语言中出现,很容易理解.它将数据和操作进行封装,以便将来的复用. 模块 模块,在Python可理解为对应于一个文件.在创建了一个脚本文件后,定义了某些函数和变量.你在其他需要这些功能 ...

  2. python之import模块及包的调用

    模块概念 在Python中,一个.py文件就称之为一个模块(Module).使用模块组织代码,最大的好处是大大提高了代码的可维护性 模块一共三种:python标准库.第三方模块.应用程序自定义模块. ...

  3. 二十五. Python基础(25)--模块和包

    二十五. Python基础(25)--模块和包 ● 知识框架   ● 模块的属性__name__ # my_module.py   def fun1():     print("Hello& ...

  4. python中的模块及包及软件目录结构规范

    知识内容: 1.模块的定义与分类 2.模块的导入 3.模块与包 4.不同目录下的模块调用 一.模块的定义与分类 1.什么是模块 模块就是实现了某个功能的代码集合,模块是由一大堆代码构成的 类似于函数式 ...

  5. python 类、模块、包的区别

    学习python的时候,碰到了import 和 from xx import xx的问题, 为了弄清楚什么是 module 和package ,这篇文章讲解的不错!! 原文: http://www.c ...

  6. Python第十章-模块和包

    模块和包 我们以前的代码都是写在一个文件中, 而且代码也比较短. 假设我们现在要写一个大的系统, 不可能把代码只写到一个文件中, 迫切想把代码写到不同的文件中, 并且能够在一个文件使用另一个文件中代码 ...

  7. Python包中 __init__.py文件的作用

    原创连接 https://www.cnblogs.com/AlwinXu/p/5598543.html Python包中 __init__.py文件的作用 在创建python包的过程中,IDE都会在包 ...

  8. python包中__init__.py文件的作用

    python包中__init__.py文件的作用 __init__.py文件最常用的作用是标识一个文件夹是一个 python包. __init__.py文件的另一个作用是定义模糊导入时要导入的内容. ...

  9. pydev package包中__init__.py作用

    Eclipse用pydev,新建一个pydev package时,总会自动地生成一个空的__init__.py文件. 原来在python模块的每一个包中,都有一个__init__.py文件(这个文件定 ...

随机推荐

  1. 疫情控制 2012年NOIP全国联赛提高组(二分答案+贪心)

    P1084 疫情控制 题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控 ...

  2. P3297 [SDOI2013]逃考

    传送门 完全看不出这思路是怎么来的-- 首先对于两个亲戚,他们监视范围的边界是他们连线的中垂线.那么对于一个亲戚来说它能监视的范围就是所有的中垂线形成的半平面交 然后如果某两个亲戚的监视范围有公共边, ...

  3. Luogu P5027 【Barracuda】(高斯消元)

    祭一下第一道独立做出来的高斯消元(虽然在各大佬看来都是水题...) 首先这道题给了你n+1个一次方程,n个未知数 其中有一个方程是错误的 求解在合法的前提下最大的未知数是多少... 显然高斯消元... ...

  4. WMI 技术

    什么是WMI? Windows Management Instrumentation (WMI)是可伸缩的系统管理结构,该规范采用一个统一.基于标准且可扩展的面向对象接口.它提供与系统管理员信息和基础 ...

  5. Android 性能优化(6)网络优化( 2) Analyzing Network Traffic Data:分析网络数据

    Analyzing Network Traffic Data 1.This lesson teaches you to Analyze App Network Traffic Analyze Netw ...

  6. Spring.Net学习笔记(2)-依赖注入

    一.开发环境 操作系统:Win10 编译器:VS2013 framework版本:.net 4.5 Spring版本:1.3.1 二.涉及程序集 Spring.Core.dll Common.Logg ...

  7. RabbitMQ系列(三)--Java API

    基于java使用RabbitMQ 框架:SpringBoot1.5.14.RELEASE maven依赖: <dependency> <groupId>com.rabbitmq ...

  8. ThinkPHP---TP功能类之联表查询

    [一]介绍 在原生的sql中使用join 语法进行数据的联表查询, 在ThinkPHP里支持联表查询操作,但是可以归纳成两种方式:table方法.join方法 (1)table方法:在TP中对应SQL ...

  9. PHP 浏览器端输出中文正常,cmd中文乱码

    cmd 运行php脚本乱码问题如果别的编码根据下面的自己换吧!chcp 65001 就是换成UTF-8chcp 936 可以换回默认的GBKchcp 437 是美国英语

  10. 【2018百度之星资格赛】 A 问卷调查 - 位运算&动规

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=6344 参考博客:在此感谢http://www.cnblogs.com/LQLlulu/p/941923 ...