前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python 模块定义、导入、优化

python 模块定义、导入、优化

作者头像
py3study
发布2018-08-02 16:11:49
1.5K0
发布2018-08-02 16:11:49
举报
文章被收录于专栏:python3python3

模块:

在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

代码语言:javascript
复制
name = "zhang"
def say_hello():
    print("hello,",name)

新建文件test.py,导入模块。注意,模块名是去除.py之后的名字

代码语言:javascript
复制
import hello
#输出变量,执行方法
print(hello.name)
hello.say_hello()

执行输出

zhang

hello, zhang

包:

用来从逻辑上组织模块,本质就是一个目录(必须带有一个__init__.py文件)

导入包的本质:

去执行包目录下的__init__.py文件

使用pycharm编辑器,新建一个包package_test

编辑__init__.py文件

代码语言:javascript
复制
print('from the package package_test')

新建一个文件p_test.py

代码语言:javascript
复制
import package_test

目录结构如下:

代码语言:javascript
复制
.
├── p_test.py
└── package_test
    └── __init__.py

执行p_test.py,输出

from the package package_test

上面介绍的模块导入,都是基于同级目录的。那么module在不同目录下,该如何导入呢?

目录结构如下:

代码语言:javascript
复制
.
├── 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

代码语言:javascript
复制
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,先来打印当前文件的绝对路径

代码语言:javascript
复制
import sys,os
print(os.path.abspath(__file__))

执行输出

E:\python_script\day5\package_test\main.py

然后获取当前目录

代码语言:javascript
复制
import sys,os
print(os.path.dirname(os.path.abspath(__file__)))

执行输出

E:\python_script\day5\package_test

最后获取上一层目录,定义变量

代码语言:javascript
复制
import sys,os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
print(BASE_DIR)

执行输出

E:\python_script\day5

这个目录,就可以找到package_test路径了!

将项目根目录添加到系统环境变量中

代码语言:javascript
复制
import sys,os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)

最后导入模块,执行函数

代码语言:javascript
复制
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方法

代码语言:javascript
复制
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里面的函数,目录结果如下:

代码语言:javascript
复制
.
├── module_test
│   └── main.py
└── package_test
    ├── __init__.py
    └── test1.py

test1.py内容如下:

代码语言:javascript
复制
def test():
    print('in the test1')

main.py直接引用package_test包,是否可以执行呢?

代码语言:javascript
复制
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文件的路径。

代码语言:javascript
复制
from . import test1

再次执行main.py

执行输出

in the test1

再深层次的目录调用,目录结果如下:

代码语言:javascript
复制
python_script/
├── day4
│   └── test.py
└── day5
    └── package_test
        ├── __init__.py
        └── test1.py

day5的代码,同上,没改动

test.py需要调用test1.py,那么需要把python_script目录加到环境变量即可

修改day4下的test.py文件

代码语言:javascript
复制
import sys,os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
print(BASE_DIR)

执行输出

E:\python_script

加载到环境变量

代码语言:javascript
复制
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

注意下面这行代码

代码语言:javascript
复制
from day5 import package_test

day5表示python_script目录下的day5

导入优化

语法:

代码语言:javascript
复制
from 模块名 import 函数或变量名

举个例子,目录结构如下:

代码语言:javascript
复制
test4/
├── module_test.py
└── test.py

module_test.py内容如下:

代码语言:javascript
复制
def test():
    print('in the test')

test.py内容如下:

代码语言:javascript
复制
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函数是否存在。

那么每执行一次,就要先找模块,再找函数,重复劳动,效率很低。

为了解决这个问题,就是在导入模块的时候,不让它找就可以了

代码语言:javascript
复制
import module_test

改成

代码语言:javascript
复制
from module_test import test

就可以了。

下面的执行方法module_test.test()改成test() 就可以了,完整代码如下

代码语言:javascript
复制
#!/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

这种方法,可以使代码执行的更快

为了避免函数重名,可以在导入的时候,起别名

代码语言:javascript
复制
from module_test import test as mod_test
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-03-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档