模块的介绍
模块
什么是模块?
为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。在Python中,一个.py文件就称之为一个模块(Module)
使用模块的好处
- 最大的好处是大大提高了代码的可维护性。其次,编写代码不必从零开始。当一个模块编写完毕,就可以被其他地方引用。我们在编写程序的时候,也经常引用其他模块,包括Python内置的模块和来自第三方的模块。
- 使用模块还可以避免函数名和变量名冲突。每个模块有独立的命名空间,因此相同名字的函数和变量完全可以分别存在不同的模块中,所以,我们自己在编写模块时,不必考虑名字会与其他模块冲突
模块的分类
- 内置标准模块(又称标准库)执行help('modules')查看所有python自带模块列表
- 第三方开源模块,可通过pip install 模块名 联网安装
- 自定义模块
模块的调用
模块的调用分为以下几种模式
import module # 正常导入
from module import xx # 从模块导入哪个函数
from module.xx.xx import xx as rename # 给导入的模块起一个别名
from module.xx.xx import * # 从绝对路径导入所有的方法
模块的使用
使用模块paramiko来进行远程连接
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('ip地址', 端口, '用户名', '密码')
stdin, stdout, stderr = ssh.exec_command('df')
print(stdout.read())
ssh.close()
#执行命令 - 通过用户名和密码连接服务器
包(Package)
一个文件夹管理多个模块,这个文件夹就称为包
包就是文件夹,但该文件夹下必须存在 __init__.py 文件, 该文件的内容可以为空。__int__.py用于标识当前文件夹是一个包。
跨模块导入
跨模块导入需要添加环境变量,把父级的path添加到sys.path里就可以使用了
import sys,os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
相对导入与绝对导入
在Python中相对导入用..表示;
绝对导入就是用文件的路径来进行导入
.
├── __init__.py
├── crm
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── tests.py
│ ├── views.py #from ..proj import settings
├── manage.py
└── proj
├── __init__.py
├── settings.py #from .import urls
├── urls.py
└── wsgi.py
views.py里代码
from ..proj import settings
def sayhi():
print('hello world!')
print(settings.DATABASES)
执行结果报错了
Traceback (most recent call last):
File "my_proj/crm/views.py", line 4, in <module>
from ..proj import settings
SystemError: Parent module '' not loaded, cannot perform relative import
其实这两个错误的原因归根结底是一样的:在涉及到相对导入时,package所对应的文件夹必须正确的被python解释器视作package,而不是普通文件夹。否则由于不被视作package,无法利用package之间的嵌套关系实现python中包的相对导入
文件夹被python解释器视作package需要满足两个条件(一般不建议使用相对导入):
- 文件夹中必须有__init__.py文件,该文件可以为空,但必须存在该文件。
- 不能作为顶层模块来执行该文件夹中的py文件(即不能作为主函数的入口)
所以这个问题的解决办法就是,既然你在views.py里执行了相对导入,那就不要把views.py当作入口程序,可以通过上一级的manage.py调用views.py
.
├── __init__.py
├── crm
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── tests.py
│ ├── views.py #from ..proj import settings
├── manage.py #from crm import views
└── proj
├── __init__.py
├── settings.py #from .import urls
├── urls.py
└── wsgi.py
事实证明还是不行,报错
ValueError: attempted relative import beyond top-level package
from .. import models
会报错的原因是,这句代码会把manage.py所在的这一层视作package,但实际上它不是,因为package不能是顶层入口代码,若想不出错,只能把manage.py往上再移一层。
正确的代码目录结构如下
packages/
├── __init__.py
├── manage.py #from my_proj.crm import views
└── my_proj
├── crm
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── tests.py
│ ├── views.py #from . import models; from ..proj import settings
└── proj
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py