模块的介绍

模块

什么是模块?

为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。在Python中,一个.py文件就称之为一个模块(Module)

使用模块的好处

  1. 最大的好处是大大提高了代码的可维护性。其次,编写代码不必从零开始。当一个模块编写完毕,就可以被其他地方引用。我们在编写程序的时候,也经常引用其他模块,包括Python内置的模块和来自第三方的模块。
  2. 使用模块还可以避免函数名和变量名冲突。每个模块有独立的命名空间,因此相同名字的函数和变量完全可以分别存在不同的模块中,所以,我们自己在编写模块时,不必考虑名字会与其他模块冲突

模块的分类

  • 内置标准模块(又称标准库)执行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需要满足两个条件(一般不建议使用相对导入):

  1. 文件夹中必须有__init__.py文件,该文件可以为空,但必须存在该文件。
  2. 不能作为顶层模块来执行该文件夹中的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
posted @ 2018-05-22 16:44  游走在边缘的人  阅读(142)  评论(0编辑  收藏  举报