发布时间:2018-03-01 14:45:55编辑:admin阅读(3658)
模块:
在Python中,一个.py文件就称之为一个模块(Module)。
它是实现了某个功能的代码集合。
模块分为三种:
1.自定义模块
2.内置标准模块(又称标准库)
3.开源模块
模块导入方法:
1. import module_name (导入一个模块)
2. import module_name,module2_name (导入多个模块)
3. from module_name import * (不推荐使用)
4. from module_name import m1 as name_m1 (导入指定的函数或变量并重命名)
5. from module_name import m1,m2,m3 (导入模块的多个函数或变量)
第3种办法,不推荐使用。因为这一段话,相当于把module_name.py的所有代码复制到当前代码中,调用的时候,直接写方法名调用,不需要module_name.方法名()这种方式调用。如果发现方法名或者变量冲突,以本代码为准。
import的本质
把导入模块的所有代码解释一遍,统一赋值给一个变量,这个变量名叫模块名。
调用变量,使用 module_name.变量名
调用函数,使用 module_name.函数名()
from的本质
把导入模块的指定函数或者变量,放到当前文件的位置,执行一遍。
调用变量或者函数的时候,直接使用即可,不需要在前面加模块名。
自定义一个模块
新建文件hello.py
name = "zhang" def say_hello(): print("hello,",name)
新建文件test.py,导入模块。注意,模块名是去除.py之后的名字
import hello #输出变量,执行方法 print(hello.name) hello.say_hello()
执行输出
zhang
hello, zhang
包:
用来从逻辑上组织模块,本质就是一个目录(必须带有一个__init__.py文件)
导入包的本质:
去执行包目录下的__init__.py文件
使用pycharm编辑器,新建一个包package_test
编辑__init__.py文件
print('from the package package_test')
新建一个文件p_test.py
import package_test
目录结构如下:
. ├── p_test.py └── package_test └── __init__.py
执行p_test.py,输出
from the package package_test
上面介绍的模块导入,都是基于同级目录的。那么module在不同目录下,该如何导入呢?
目录结构如下:
. ├── hello.py └── package_test ├── __init__.py └── main.py
main.py需要导入hello模块
先来分析一个导入模块的执行步骤
import module_name->找到module_name.py文件->找到module_name.py的路径->sys.path(搜索路径)
编辑main.py,打印sys.path
import sys print(sys.path)
使用cmd执行,执行输出
['E:\\python_script\\day5\\package_test', 'C:\\Program Files\\Python36\\python36.zip', 'C:\\Program Files\\Python36\\DLLs', 'C:\\Program Files\\Python36\\lib', 'C:\
\Program Files\\Python36', 'C:\\Program Files\\Python36\\lib\\site-packages']
第一个元素,就是当前路径
如果一个元素找不到,就会找下一个元素,直到所有的目录都还找不到的话,就报错
ModuleNotFoundError: No module named 'xxx'
为了解决这个问题,需要加一个路径,必须要包含需要导入模块的路径。这个路径,一般为项目根目录。
编辑main.py,先来打印当前文件的绝对路径
import sys,os print(os.path.abspath(__file__))
执行输出
E:\python_script\day5\package_test\main.py
然后获取当前目录
import sys,os print(os.path.dirname(os.path.abspath(__file__)))
执行输出
E:\python_script\day5\package_test
最后获取上一层目录,定义变量
import sys,os BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) print(BASE_DIR)
执行输出
E:\python_script\day5
这个目录,就可以找到package_test路径了!
将项目根目录添加到系统环境变量中
import sys,os BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR)
最后导入模块,执行函数
import sys,os BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) import hello hello.say_hello()
执行输出
hello, zhang
注意:
sys.path.append(BASE_DIR) 是将项目根目录追加到最后一个列表元素。如果中间某一个元素,正好找到了指定文件,比如hello.py,那么就不会再查找后面的路径了,直接加载。
如果出现了这种情况,必须要把BASE_DIR插入到第一个元素位置,使用insert方法
sys.path.insert(0,BASE_DIR) print(sys.path)
执行输出
['E:\\python_script\\day5', 'E:\\python_script\\day5\\package_test', 'E:\\python_script', 'C:\\Program Files\\Python36\\python36.zip', 'C:\\Program Files\\Python36\\DLLs', 'C:\\Program Files\\Python36\\lib', 'C:\\Program Files\\Python36', 'C:\\Program Files\\Python36\\lib\\site-packages']
举另外一个例子
main.py需要调用test1.py里面的函数,目录结果如下:
. ├── module_test │ └── main.py └── package_test ├── __init__.py └── test1.py
test1.py内容如下:
def test(): print('in the test1')
main.py直接引用package_test包,是否可以执行呢?
import sys,os BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) import package_test package_test.test1.test()
执行报错
ModuleNotFoundError: No module named 'test1'
因为import package_test 这一步是执行package_test目录下的__init__.py文件,而这个文件是空的
修改__init__.py文件,从当前目录下,导入test1模块
这个 点 表示相对于__init__.py文件的路径。
from . import test1
再次执行main.py
执行输出
in the test1
再深层次的目录调用,目录结果如下:
python_script/ ├── day4 │ └── test.py └── day5 └── package_test ├── __init__.py └── test1.py
day5的代码,同上,没改动
test.py需要调用test1.py,那么需要把python_script目录加到环境变量即可
修改day4下的test.py文件
import sys,os BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) print(BASE_DIR)
执行输出
E:\python_script
加载到环境变量
import sys,os BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) from day5 import package_test package_test.test1.test()
执行输出
in the test1
注意下面这行代码
from day5 import package_test
day5表示python_script目录下的day5
导入优化
语法:
from 模块名 import 函数或变量名
举个例子,目录结构如下:
test4/ ├── module_test.py └── test.py
module_test.py内容如下:
def test(): print('in the test')
test.py内容如下:
import module_test def logger(): module_test.test() print('in the logger') def search(): module_test.test() print('in the search') #假设有N个函数在调用module_test.test() #... logger()
执行输出
in the test
in the logger
module_test.test()在执行的时候,先找到module_test模块,再从里面检索test函数是否存在。
那么每执行一次,就要先找模块,再找函数,重复劳动,效率很低。
为了解决这个问题,就是在导入模块的时候,不让它找就可以了
import module_test
改成
from module_test import test
就可以了。
下面的执行方法module_test.test()改成test() 就可以了,完整代码如下
#!/usr/bin/env python # coding: utf-8 __author__ = 'www.py3study.com' from module_test import test def logger(): test() print('in the logger') def search(): test() print('in the search') #.... logger()
执行输出
in the test
in the logger
这种方法,可以使代码执行的更快
为了避免函数重名,可以在导入的时候,起别名
from module_test import test as mod_test
上一篇: python 软件目录结构规范
47745
46237
37110
34627
29229
25886
24745
19863
19417
17909
5716°
6315°
5836°
5888°
6985°
5829°
5846°
6361°
6316°
7673°