使用Python模块常见的情况是,事先写好A.py文件,需要import B.py文件时,先拷贝到当前目录,然后再import
这样的做法在程序量较小的情况下是可行的,如果程序交互复杂程度稍高,就很费力了
有一种解决方法可以将多个.py文件组织起来,方便在外部统一调用,和在内部互相调用:python中的 __init__.py在包调用中起到了重要的作用
首先要明确的Python在执行import包的时候,执行的操作,按照python的文档描述,操作如下:
a) 创建一个新的,空的module对象(它可能包含多个module);
b) 把这个module对象插入sys.module中
c) 装载module的代码(如果需要,首先必须编译) (首先需要找到module程序所在的位置,其原理为:如果需要导入的module的名字是m1,则解释器必须找到m1.py,它首先在当前目录查找,然后是在环境变量PYTHONPATH中查找)
d) 执行新的module中对应的代码。
Python中的package定义很简单,其层次结构与.py所在目录的层次结构相同,比较关键的一点是package中必须包含一个__init__.py的文件
例如,我们可以这样组织一个package: init为顶层目录
运行结果如下
其中__init__.py可以为空,只要它存在,解释器对其视作一个package处理。
第一层:pack, pack2, main.py
第二层 pack: __init__.py,module_A.py
pack2:__init__.py,module_B.py
main.py 调用脚本:
from pack import func1
from pack import func2
from pack2 import print_lst
def main():
func1()
func2()
print_lst()
if __name__ == "__main__":
main()
其中 module_A:
def func1():
print("MODULEAAAAA_func1111")
def func2():
print("MODULEAAAAA_func2222")
同一层 __init__.py
from .module_A import func1
from .module_A import func2
.module_A 表示__init__.py同一层目录的module_A
个人理解是:当 main.py调用脚本from pack import func1
由于from操作 会默认目录下存在pack包,解释器会首先寻找__init__.py
而__init__.py内容不为空,对module_A引入了两个函数fun1,fun2,生成了函数引用域(太菜不知道专属名词)
所以在main.py 中可以不显式地指明module_A而直接用: from pack import fun1,fun2
如果把pack下的init.py 的第二行 import func2注释
也就是说,package内的module的import 是受__init__.py限制的
有时在import语句中会出现通配符*,导入某个module中的所有元素,这是怎么实现的呢?
答案就在__init__.py中。如果在__init__.py文件中写(指定)
__all__ = ['module_A']
如果改为
__all__ = []
Traceback (most recent call last):
File "", line , in
ImportError: No module named module_A
运行则会报错,如上
这也就是说,package内的module的导入是受__init__.py限制的
好了,最后来看看,如何在package内部互相调用。
如果希望调用同一个package中的module,则直接import即可。
也就是说,在module_A.py中,可以直接使用import module_others
如果不在同一个package中,例如我们希望在module_A.py中调用module_B.py中的FuncB,则应该这样:
from module_B的包名(目录).module_B import funcB
【转】【Python】Python中的__init__.py与模块导入(from import 找不到模块的问题)
python中的Module是比较重要的概念.常见的情况是,事先写好一个.py文 件,在另一个文件中需要import时,将事先写好的.py文件拷贝 到当前目录,或者是在sys.path中增加事先写好的 ...
Python中的__init__.py的作用
当用 import 导入该目录时,会执行 __init__.py 里面的代码 因此在__init__.py文件中,把深层的包的路径缩短,别的地方就可以在引用到目录级别时引到深层的包.
Python中【__all__】的用法
Python中[__all__]的用法 转:http://python-china.org/t/725 用 __all__ 暴露接口 Python 可以在模块级别暴露接口: __all__ = [&q ...
python2中的__init__.py文件的作用
python2中的__init__.py文件的作用: 1.python的每个模块的包中,都必须有一个__init__.py文件,有了这个文件,我们才能导入这个目录下的module. 2.__init_ ...
Python中logging模块的基本用法
在 PyCon 2018 上,Mario Corchero 介绍了在开发过程中如何更方便轻松地记录日志的流程. 整个演讲的内容包括: 为什么日志记录非常重要 日志记录的流程是怎样的 怎样来进行日志记录 ...
Python中zip()与zip(*)的用法
目录 Python中zip()与zip(*)的用法 zip() 知识点来自leetcode最长公共前缀 Python中zip()与zip(*)的用法 可以看成是zip()为压缩,zip(*)是解压 z ...
简单说明Python中的装饰器的用法
简单说明Python中的装饰器的用法 这篇文章主要简单说明了Python中的装饰器的用法,装饰器在Python的进阶学习中非常重要,示例代码基于Python2.x,需要的朋友可以参考下 装饰器对与 ...
随机推荐
iOS-点击推送消息跳转处理
当用户通过点击通知消息进入应用时 - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDi ...
CSS效果
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs& ...
codeforces 395B2 	 iwiwi
#include #include using namespace std; ]="iiiiiiiiiiiiiiiiiiiiii&q ...
手机端轻应用模拟原生的下拉刷新效果(JavaScript)
方案一:使用iscoll等有下拉功能的框架. 分析:因为项目的结构已经基本完成,再使用框架,会与原来的结构互相影响: 方案二:用JavaScript.Jquery写. 分析:可能没有直接使用框架的效果 ...
IntelliJ 一键添加双引号
IntelliJ IDEA(目前最新版本为2016.2.5) 不直接支持一键向选取内容添加双引号,但可以通过配置 Live Template 实现此功能. 以下为配置方法(针对2016.2.5版,其它 ...
Java中sleep,wait,yield,join的区别
sleep() wait() yield() join()用法与区别 1.sleep()方法 在指定时间内让当前正在执行的线程暂停执行,但不会释放“锁标志”.不推荐使用. sleep()使当前线程 ...
JBoss7安装、测试、配置和启动以及停止,部署
转:http://www.hongyanliren.com/2014m01/3013.html 内容概要 JBoss系列三主要目的是演示如何部署应用到JBoss7/WildFly,如下图中描述了部署应 ...
PYQT4 : QSystemTrayIcon练习
照着demo自己做了一遍,练练手 import sys from PyQt4 import QtGui from PyQt4 import QtCore class SysTray(QtGui.QDi ...
Entity Framework 调用返回标量值的存储过程
最近项目用到EF,虽然说EF与Linq To SQL有很多地方相似,但是EF(这里指3.5版,4.0版的还没去留意)确实有些地方做得不够方便. 就拿存储过程来说吧,EF里面想调用存储过程不是直接在数据 ...
windows安装IDEA
1.安装下载 https://www.jetbrains.com/idea/download/#section=windows 2.服务器激活地址: 39.129.9.34:8888 https:// ...