在python中用来引入模块的是_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.class2
module1.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']
$cattest.py
from package1 import*module1.class1().hello()
module2.class2().hello()
# 运行脚本
$ python3 test.pyI am class1 in module1
I 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')
$cattest.py
from package1 import module1, module2, class3
module1.class1().hello()
module2.class2().hello()
class3().hello()
$ python3 test.py
I am class1inmodule1
I am class2inmodule2
I am class3in __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
【在python中用来引入模块的是_python模块引用】__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')
$cattest.py
import sys, os
curr_dir= os.path.dirname(os.path.realpath(__file__))
sys.path.append(curr_dir) # 这里我们添加了环境变量
from package1 import module1, module2
module1.class1().hello()
module2.class2().hello()
module2.class3().hello() # 通过package1的module2引用到了package2中module3下的class3
请注意其中的注释。test.py 脚本运行结果如下:
$ python3 test.py
I am class1inmodule1
I am class2inmodule2
I am class3in module3 which of package2
根据我们工程的实际情况可能会有很多更复杂的情况,其原理是不变的。
推荐阅读
- python|python wx模块详解_python中wx模块的具体使用方法
- python中直方图bins是什么意思_Python 中下划线的 5 种含义都是什么()
- python中的modify是什么意思_理解Python中的装饰器
- 投稿|中企出海:不只钱那么简单
- 投稿|请周董在微信开演唱会,腾讯音乐能否扭转颓势?
- 网站日志中显示 Mozilla/5.0 (Linux; Android 4.4.2; HG680-KA Build/KOT49H) AppleWebKit/537.36 (KHTML, like Ge
- .net core读取appsettings.config中文乱码问题
- 创建并运行rn app项目
- 投稿|「机战」印度,中国厂商们的远虑和近忧
- Selenium中的自动化(页面对象模型和页面工厂)