python模块引用
前言
在软件工程中,我们从大的宏观方向,要看业务目标、工程架构,到具体实施时就要选择适合工程实现的编程语言和配套组件。在选择编程语言时根据项目的不同,我们可能会有很多需要考虑的因素,从编程语言本身的角度来看,他们是“大同小异”的,但如果从差异角度看,每种编程语言除了语法体现不同外,执行方式、性能、内存管理、模块组织、组件、第三方库等又会有很大差异,但这些却又是我们要需要考虑的关键点。
下面我们聊一下python语言的模块引入方式,当我们知道了其引入方式,那么组织模块就是自己的事了~~
当然,本文中不一定会列出所有引入方式,我们只关注常用的、个人认为较好的方式。
在开始聊这个话题前,我们首先要区分的概念是 package、module、class,我们粗略总结:
1. package是一个层级的概念,它通常是一个目录,在package中可能会包含多个module;
2. module是一个文件(通常是package中的文件),在文件中我们可以定义类或函数等;
3. class 类,它被包含在module文件中;
然后,对于引用格式,我们做一个“感性”的总结就是:package要用“from”,module和class要用import,如:
from package import module
import package.module # 注意,不能这样引用:import package.module.class
基本的模块引入方式
为方便举例说明,现假设有如下目录结构及文件:
$ tree . ├── package1 │ ├── module1.py │ └── module2.py └── test.py$ cat package1/module1.py class class1:def hello(self):print('I am class1 in module1')$ cat package1/module2.py class class2:def hello(self):print('I am class2 in module2')$ cat test.py from package1 import module1 # 方式1 from package1.module2 import class2 # 方式2 注意,不能这样引入:import package1.module2.class2module1.class1().hello() class2().hello()
可以看到,test.py中展示了两种基本的引入模块和类的方式,并调用了hello方法。我们执行test.py,结果如下:
$ python3 test.py I am class1 in module1 I am class2 in module2
当然我们还可以用其他方式引入模块,例如我们修改test.py文件为 :
import package1.module1 import package1.module2 from package1 import * # 注意,前面一定要有两个import语句,否则是不正确的module1.class1().hello() module2.class2().hello()
这种方式没有语法错误,但个人不建议用这种方式,因为不太直观。
进一步理解模块的概念
细心的你可以已经注意到,上面的目录结构中不能直接引入package1中的所有模块(from package1 import * ),这是为什么呢?
其实原因很简单:因为现在的package1还是一个普通的目录,还算不上是一个真正意义上的package,需要在package下放一个__init__.py文件来标识当前目录为一个package!
这里要说一下,我们在设计python程序的时候,只要是我们认为应该是一个package的目录都应该包含一个__init__.py文件(即使该文件为空)。
下面我们在package1目录下添加空的__init__.py文件,并修改test.py文件内容:
$ tree . ├── package1 │ ├── __init__.py │ ├── module1.py │ └── module2.py └── test.py $ cat test.py from package1 import *module1.class1().hello()module2.class2().hello()
如果此时执行test.py会发现依然报错!
这是因为,虽然此时package1是一个“package”了,但__init__.py文件内容为空(我们可以把__init__.py文件看做是一个package的“对外接口”,可以起到屏蔽“包”内细节的做用)。使用__init__.py文件一般需要注意以下两点:
1. __init__.py文件内一般使用 __all__ 关键字来限定package内对外的模块。
2. __init__.py文件尽量“轻”,即最好不要在里面定太多代码(如定义类等),虽然这样做不会报错。
下面通过修改__init__.py文件和test.py文件来分别说明__init__.py文件的使用方式:
$ cat package1/__init__.py __all__ = ['module1', 'module2']$ cat test.py from package1 import *module1.class1().hello() module2.class2().hello() # 运行脚本$ python3 test.py I am class1 in module1I am class2 in module2
当然,如果__init__.py文件内包含某个类,package外面也可以直接访问到,如:
$ cat package1/__init__.py __all__ = ['module1', 'module2']class class3:def hello(self):print('I am class3 in __init__.py')$ cat test.py from package1 import module1, module2, class3module1.class1().hello() module2.class2().hello() class3().hello()$ python3 test.py I am class1 in module1 I am class2 in module2 I am class3 in __init__.py
注意,test.py 文件中指明了需要引入的内容 (from package1 import module1, module2, class3),如果将这个引入方式改为全部引入(from package1 import * )则会报错,因为 import * 引入的package内容需要__init__.py文件中__all__关键字指定!
当然,如果要引入具体module的所有内容,可以通过 import * 的方式,如:from package1.module1 import *
更复杂的引用
我们可以想到,引用还有很多其他情况,如不同package间、不同目录下或不同层级目录下的相互引用等。
其实,所有的引用,在了解了以上原理后都是很好了解的,不过这里还要先提一下”环境变量“,关于环境变量概念和作用这里略过。python添加环境变量的方法:
sys.path.append('user_path') # 其中 user_path 即我们要添加的路径
添加到环境变量中的路径,在本工程中各文件中都可以直接访问到。下面我们利用和之前相似的例子进行说明。
假设我们现在有一个和package1同级的包,package2,且package2中有一个moudle3.py文件,此时package1中的module2文件需要访问package2的module3.py,文件目录及内容如下:
$ tree . ├── package1 │ ├── __init__.py │ ├── module1.py │ └── module2.py ├── package2 │ ├── __init__.py │ └── module3.py └── test.py$ cat package1/__init__.py __all__ = ['module1', 'module2']$ cat package1/module1.py class class1:def hello(self):print('I am class1 in module1')$ cat package1/module2.py from package2.module3 import class3 # 这里我们引用了package2的class3 class class2:def hello(self):print('I am class2 in module2')$ cat package2/__init__.py __all__ = ['module3']$ cat package2/module3.py class class3:def hello(self):print('I am class3 in module3 which of package2')$ cat test.py import sys, os curr_dir = os.path.dirname(os.path.realpath(__file__)) sys.path.append(curr_dir) # 这里我们添加了环境变量from package1 import module1, module2module1.class1().hello() module2.class2().hello() module2.class3().hello() # 通过package1的module2引用到了package2中module3下的class3
请注意其中的注释。test.py 脚本运行结果如下:
$ python3 test.py I am class1 in module1 I am class2 in module2 I am class3 in module3 which of package2
根据我们工程的实际情况可能会有很多更复杂的情况,其原理是不变的。
转载于:https://www.cnblogs.com/wwjneu/p/9802154.html
python模块引用相关推荐
- python包引用问题
python模块引用梳理 文件组织结构: 复制代码 t ├── __init__.py ├── main.py ├── t1 │ ├── A.py │ └── __init__.py └── t2 ├ ...
- python自己创建模块引用失败_详解Python import方法引入模块的实例 Python怎么import自己写的模块...
python中 import导入模块失败的问题? python中的import引用不了模块我傻,为你傻;我痛,为你痛;深夜里,你是我一种惯性的回忆. 为什么我用from lianxi import*就 ...
- 扩展Python模块系列(四)----引用计数问题的处理
承接上文,发现在使用Python C/C++ API扩展Python模块时,总要在各种各样的地方考虑到引用计数问题,稍不留神可能会导致扩展的模块存在内存泄漏.引用计数问题是C语言扩展Python模块最 ...
- python3 模块调用其他类的方法_python类的函数调用 python如何引用其他模块中类的方法中的变量?...
python中类内部的函数可以互相调用吗? python 如何调用类的方法要遇上一个人只要用一分钟的时间:要喜欢上一个人只要用一句话的时间:要爱上一个人只要用一天的时间:但要忘记一个人却要用一生的时间 ...
- python模块相互引用_python导入模块交叉引用的方法
实际项目中遇到python模块相互引用问题,查资料,终于算是弄明白了. 首先交叉引用或是相互引用,实际上就是导入循环,关于导入循环的详细说明,可见我摘自<python核心编程>第二版的摘抄 ...
- 遇到问题–python–pytest引用模块错误
转载请注明出处:遇到问题–python–pytest引用模块错误 遇到问题 python项目结构如图: main.py中引用了 import pandas as pd 运行main.py文件没问题,但 ...
- Python接口测试-模块引用与映射
PyCharm中发现模块引用老是有各种问题 可以用映射来解决,例如需要调用登录模块里面的东西的时,可以这样处理: 登录模块:1-login.py import this import requests ...
- [ 转]Python模块(二)import和from...import的区别
Python模块(二)import和from...import的区别 听语音 原创 | 浏览:2975 | 更新:2018-04-02 13:02 | 标签:PYTHON 1 2 3 4 5 6 7 ...
- 如何获取本地安装的Python模块列表?
我想获得Python模块的列表,这些模块在我的Python安装(UNIX服务器)中. 如何获得计算机中安装的Python模块的列表? #1楼 使用pkgutil.iter_modules非常简单的搜索 ...
最新文章
- C 语言编程 — 编程实践
- 如何查看AWS实例上使用的key value pair名称
- 高校何时开学?教育部回应
- Permission denied的解决办法
- ruby gem 安装mysql2_Ruby gem mysql2安装错误
- mybatis mysql 事务处理_详解Java的MyBatis框架中的事务处理
- 广二师的计算机专业好不,广东技术师范学院和广东第二师范学院哪一个更好?...
- 【maven】idea maven slf4j : StackOverflowError
- 【软件设计师考试】《软件设计师教程》(一)
- 80psi等于多少kpa_psikpa换算(kpa bar 换算)
- Bone Collector——01背包
- 模电学习笔记(十三)——控制直流偏执电路
- 【Python爬虫】IOS苹果商店指定APP评论爬取
- TikTok搬运视频怎么做,搬运怎样的视频最好
- 鸣人来教你安装配置JDK
- 如何测算BMI指数(Python)
- 分布式搜索引擎ElasticSearch(二)---ElasticSearch进阶使用教程
- 启英泰伦CI-C22GS02(ci1122)单麦离线智能语音模块制作声控小台灯
- 用python对股票进行可视化分析_股票分析 | 用Python玩玩A股股票数据分析-可视化部分...
- 2-github术语介绍
热门文章
- 套路、逻辑与思辨(道理的论证)
- AngularJS之禅
- AS3.0函数定义的方法
- 嵌入式SQL程序的VC+SQL server 2000实现的环境配置
- 深入探讨 Java 类加载器
- ASP.NET MVC Bundles 之学习笔记
- Git图文教程:从零到上传GitHub项目
- [转]---UAP中如何判断当前APP在哪个平台设备上运行
- sqlserver 两表联查去重_去山东省(烟台)必吃“特色”小吃 ,舌尖5大美食享受!...
- hdu4973 线段树(题目不错,用了点,段,更新查找还有DFS)