zoukankan      html  css  js  c++  java
  • 常用模块

    本文概要

    本文主要讲解以下几个知识点:

    1. 认识什么是模块

    2. 模块有什么好处

    3. 模块的分类

    4. 模块的导入方法

    5. 第三方开源模块的安装方法

    6. 包的知识

     

    什么是模块

    在平时的开发过程中,随着代码越写越多,到最后如果要对某一处进行修改就显得难以维护了,稍不注意要是改错了就会出大问题。

    所以为了维护的便捷,我们就把很多函数进行分组,放到不同的文件里,就可以通过文件名本身进行功能区分,每个文件里的代码量也会相对较少,更有利于维护,很多语言都是这样的,在Python里,一个.py文件就是一个模块。

    使用模块有什么好处

    1. 提高代码可维护性;

    2. 可重用,编写代码不必从零开始,直接引用即可,其他地方也可以用;

    3. 避免函数名和变量名冲突,因为一个文件中如果代码太多,就会声明有很多的函数名和变量名,有时候你在定义一个变量名时,自己都不知道是否已经用过了,分为多个文件,文件各自的作用域第独立的,所以能够尽量避免函数名和变量名的冲突。

    模块的分类

    1. 内置标准模块(又称标准库),是Python安装后自带的模块;

    2. 第三方开源模块:从其他拷贝过来的,或第三方网站上安装的,通常从https://pypi.org/安装

    3. 自定义模块:即自己写的,一个.py文件,里面写几个函数,也可以是模块。

    导入模块的方法

    # 导入整个sys模块,使用sys模块时,需要在功能前面加上sys,如:sys.getrecursionlimit()
    import sys
    
    # 从os模块中,只导入rmdir和rename两个功能,多个功能用逗号隔开。使用时功能前面不用加os,直接就可以使用,如:rmdir("abc.txt")
    from os import rmdir, rename
    
    # 从django的子模块core中导入handlers功能
    from django.core import handlers
    
    # 模块太长了,导入multiprocessing模块并通过as取一个别名叫mul
    import multiprocessing as mul
    
    # 导入socket模块下所用的功能。
    from socket import 

    注意:模块一旦被调用,就相当于执行了里面的代码。所以模块顶层一般不写执行代码,特殊除外。

    模块的导入路径

    导入自己的模块的是要要注意路径问题,相对路径和绝对路径。

    Python默认的模块在哪里:

    可以通过sys.path看到python使用哪些地方找的:

    >>> import sys
    >>> sys.path
    ['', 'D:\PycharmProjects\python_fullstack_middle\venv\Scripts\python36.zip', 'C:\Python36\DLLs', 'C:\Python36\lib', 'C:\Python36', 'D:\PycharmProjec
    ts\python_fullstack_middle\venv', 'D:\PycharmProjects\python_fullstack_middle\venv\lib\site-packages', 'D:\PycharmProjects\python_fullstack_middle\ve
    nv\lib\site-packages\setuptools-39.0.1-py3.6.egg', 'D:\PycharmProjects\python_fullstack_middle\venv\lib\site-packages\pip-9.0.3-py3.6.egg']
    >>>

    第一个元素为空,表示是当前目录。

    内置的模块和从第三方装的模块都会放到 site-packages 目录下。

    添加自定义模块目录到sys.path里面:

    sys.path.append("D:\abc") # 表示我的模块存在D盘的abc目录下

    导入和移除模块:

    import my_module
    del my_module

    开源模块的学习和安装方式

    https://pypi.org/ 是Python的开源模块库,全世界的开发者都可以在上面贡献自己的模块。

    两种安装方式:

    这里以大王的一个例子项目为例:alex_sayhi  ,搜索这个项目 点进去就会有安装方式。

    方式一(源码安装):

    如大王的项目,搜索到后,点击Download files 就可以找到下载链接,下载下来后解压,然后执行:

    python setup.py build  # 编译源码
    python setup.py install  # 安装源码

    方式二(通过pip安装):

    在项目页面上方就直接有安装命令:

    pip install alex_sayhi

    这种方式最简单,安装后在 site-packages 目录里面可以找到。

    安装的时候的输出:

    C:>pip install alex_sayhi
    Collecting alex_sayhi
      Downloading https://files.pythonhosted.org/packages/84/14/b59d93276c86f6ab556cfa7c2d860b742c1611b601cc4c7743d129b4b52a/alex_sayhi-1.0.0.tar.gz
    Installing collected packages: alex-sayhi
      Running setup.py install for alex-sayhi ... done
    Successfully installed alex-sayhi-1.0.0
    You are using pip version 9.0.1, however version 10.0.1 is available.
    You should consider upgrading via the 'python -m pip install --upgrade pip' command.
    
    C:>

    国内源:

    从官网安装可以由于一些网络因素会很慢,我们可以选择使用国内的豆瓣源。

    pip install -i http://pypi.douban.com/simple/ alex_sayhi --trusted-host pypi.douban.com   #alex_sayhi是模块名

    例子:

    这里演示一个通过ssh执行命令的小程序:

    需要导入两个模块:sys 和 paramiko sys只用到两个功能,所有通过 from sys import stdin, stdout 只导入两个功能

    paramiko 不存在,需要新安装。

    这地方有个坑的地方,我在cmd中通过 pip install paramiko 已经安装成功了,在cmd的python解释器里也能通通过 import paramiko导入模块,但是在PyCharm里面弄死导不进去,模块是已经确认安装到了C:Python36Libsite-packages 的,在PyCharm里通过print(sys.path)查看发现没有 C:Python36Libsite-packages 这个目录,这就是为什么导入不进去的原因,但是怎么加进去呢?没有找到方法。我通过另一种方式成功导入了,首先在PyCharm里先将 import paramiko敲上,paramiko会变红,双击paramiko然后按下Alt+Enter键就会提示你安装了,安装完了发现他是安装到我项目下的 \venv\lib\site-packages 目录的,anyway 反正是可以正常工作了。

    收点费

    
    
    
    from sys import stdin, stdout
    
    import paramiko
    
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect("192.168.1.100", 22, "root", "123456")
    
    stdin, stdout, stderr = ssh.exec_command("df -h")
    print(stdout.read())
    ssh.close()

    输出:

    b'Filesystem            Size  Used Avail Use% Mounted on
    /dev/xvda1             20G  9.9G  8.8G  53% /
    tmpfs                 7.8G  8.0K  7.8G   1% /dev/shm
    /dev/mapper/VolGroup-data
                          788G  604G  145G  81% /data
    '

    当模块越来越多时,一个大的功能可能包含多个模块,这时候我们可以将他们分类放到一个统一的目录当中,又或者把与数据库交互的放到一个目录,与页面展现的放到一个目录,一个目录管理多个模块,这个目录就是包。

    如何确定这个目录是包:

    python2 中目录下必须要有一个空文件 __init__.py 目录就会自动识别为包,没有的话就是一个普通目录。

    python3 可以不需要这个空文件,但是还是建议加上。

    用了包之后模块怎么导入:

    三种情况

    如下,现在的目录结构如下:

    第一种:运行文件在包之外。

    现在manage.py 调 crm包下的 view.py模块。

    在 crm/view.py 里的代码如下:

    def show_pic():
        print("show pic")
    
    
    def show_file():
        print("show_file")

     manage.py 和 crm、database两个包是同级的,在manage.py里调 view.py 模块:

    manag.py的代码如下:

    from crm import view;
    
    view.show_pic()

     运行 manage.py 的结果为:

    show pic

      这里在PyCharm里 有红色的报错,但是没有影响:

    第二种:模块在同一个包内

    现在 ui.py 模块要调 view.py 模块。

    ui.py 代码如下:

    import view
    
    view.show_pic()

     运行 ui.py 结果为:

    show pic

    没有问题,导入成功。 PyCharm 依然会有红色报错,不影响,不管他

    第三种:导入的模块在另一个包下面

    现在 ui.py 要导入在database包下面的 db.py

    这时候再像之前搞那样导入就会出现问题了,需要添加环境变量来实现,就是将crm上一层的路径 也就是 包 添加到 sys.path 中

    ui.py 代码如下:

    import sys
    
    sys.path.append("D:PycharmProjectspython_fullstack_middle第二模块:函数编程第2章.常用模块包")  # 添加环境变量
    from database import db  # 导入database下的db模块
    
    db.mysql()  # 调用db模块里的函数

    运行 ui.py 结果如下:

    mysql

    没有问题,成功。

    但是上面添加环境变量时写的是绝对路径,假如我将程序拷贝到其他人机器上,那必然会报错,所以 我们来调整一下。

    调整后 ui.py 的代码如下:

    import sys, os
    
    BASE_PATH1 = os.path.dirname(__file__)  # 通过 os.path.dirname(__file__) 获取到 ui.py 的所在目录路径
    BASE_PATH2 = os.path.dirname(os.path.dirname(__file__))  # 再包一层 os.path.dirname() 又继续向上获取一层
    
    print(BASE_PATH1)  # 输出:D:/PycharmProjects/python_fullstack_middle/第二模块:函数编程/第2章.常用模块/包/crm
    print(BASE_PATH2)  # 输出:D:/PycharmProjects/python_fullstack_middle/第二模块:函数编程/第2章.常用模块/包
    
    sys.path.append(BASE_PATH2)
    from database import db  # 导入database下的db模块
    
    db.mysql()  # 调用db模块里的函数

    运行 ui.py 结果为:

    D:/PycharmProjects/python_fullstack_middle/第二模块:函数编程/第2章.常用模块/包/crm
    D:/PycharmProjects/python_fullstack_middle/第二模块:函数编程/第2章.常用模块/包
    mysql

     成功,没有问题,并且实现了动态的路径获取。

    再来一个问题,我之前是在 crm/ui.py 模块中调 database/db.py 模块,运行的 ui.py 模块,

    现在 我还是 在 crm/ui.py 模块中调 database/db.py 模块,不过 我现在在 db.py 模块中 再调 database包下的 happy.py 模块 ,还是运行的 ui.py ,这时候你就想呀 happy.py 模块 和 db.py 都在同一个目录下 那就再db.py模块中直接写 import happy ,这时候你会发现报错了 "No module named 'happy'",咋回事,这是因为你运行的是 ui.py ,ui.py 里你直接写 import happy 它会从ui.py 同级的包里去找,肯定是找不到的,由于你已经ui.py上上级的的路径添加到环境变量sys.path了,所以要写成   from database import happy 就不会出错了。

     绝对导入与相对导入

    上面讲的就是绝对导入。

    接下来讲解 相对导入。

    在 linux 中,我们可以通过 cd .. 回到上一层 , cd ../../ 回到上上层,在python中也是可以的。

    如下图,我在crm/view.py 模块中 通过相对导入 导入database/db.py ,然后运行view.py 结果报错了 ValueError: attempted relative import beyond top-level package

     为什么会这样呢?

    因为 在涉及到相对导入时,package所对应的文件夹必须正确的被python解释器视作package,而不是普通文件夹。否则由于不被视作 package,无法利用package之间的嵌套关系实现python中包的相对导入。

    文件夹被python解释器视作package需要满足两个条件:

    1. 文件夹中必须有 __init__.py 文件,该文件可以为空,但必须存在该文件。

    2. 不能作为顶层模块来执行该文件夹中的py文件(即不能作为主函数的入口)

    也就是说,你如果view.py使用相对对导入的方式,就不要把view.py 作为入口程序,就不能直接运行 view.py.

    解决办法就是可以通过上一级的 manage.py 来调用 view.py

    好,现在我运行 manage.py ,擦, 还是报一样的错,搞毛线啊:

     但是 我如果在 view.py 里 把  from ..database import db  改为 from . import ui  就改为导入和view.py 同级的 ui.py ,再执行 manage.py 就不会报错。

     ok, 那怎么才能够 使用  from ..database import db 并且不报错呢?

    将 manage.py 往上移动一级,因为  from ..database import db 会把 manage.py 所在的这一层视作package,但实际上它不是,因为package不能是顶层入口diamante,若不像出错,只能把manage.py往上移一层。

    这里我新建一个 pack包,然后将crm 和 database都移动进去,修改manage.py 改为 from pack.crm import view  再次执行 就不会报错了。

    注意:虽然python支持相对导入,但对模块间的路径关系要求比较严格,处理不当就容易出错,所以不建议在项目里使用。

  • 相关阅读:
    多点触摸时代来了,第一个是什么呢
    能看出点幻影刺客的风采
    XNA 贴图载入的新状况
    WAR3的模型,幻影刺客,我来了。
    幻影刺客跑起来啦
    TM2T入手
    哥们儿,你终于来了….哈哈,等的花儿都谢了。
    鸣谢 MAGOSX.com
    彩色版幻影刺客留念
    好吧,效果先到这里吧
  • 原文地址:https://www.cnblogs.com/alexchenx/p/9172458.html
Copyright © 2011-2022 走看看