python代码组织及模块使用

一、python代码组织

python和其他编程语言一样,采用包管理代码,一个包中可包含许多模块。

使用模块最大的好处是大大提高了代码的可维护性。其次,编写代码不必从零开始。当一个模块编写完毕,就可以被其他地方引用。我们在编写程序的时候,也经常引用其他模块,包括Python内置的模块和来自第三方的模块。

使用模块还可以避免函数名和变量名冲突。相同名字的函数和变量完全可以分别存在不同的模块中,因此,我们自己在编写模块时,不必考虑名字会与其他模块冲突。但是也要注意,尽量不要与内置函数名字冲突。点这里查看Python的所有内置函数。

为了避免模块名冲突,python引入了按目录来组织模块的方法,称为包(package。引入包后,只要顶层的包名不与别人冲突,那所有模块都不会与别人冲突。

每一个包目录下都会有一个__init__.py的文件,这是包的标志文件,只有目录下有此文件才是一个python包。

__init__.py可以是空文件,也可以有python代码,因为__init__.py本身就是一个模块,模块名为目录名。 

上面是一个两级包目录结构,abc.py的模块名是mycompany.abcwww.py的模块名为mycompany.web.www,两个文件utils.py的模块名分别是mycompany.utilsmycompany.web.utils

注:模块名不要和系统模块名冲突,最好先查看系统是否已存在该模块,检查方法是在Python交互环境执行import abc,若成功则说明系统存在此模块。

二、使用模块 

一个标准的模块示例如下:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

' a test module '

__author__ = 'Michael Liao'

import sys

def test():
    args = sys.argv
    if len(args)==1:
        print('Hello, world!')
    elif len(args)==2:
        print('Hello, %s!' % args[1])
    else:
        print('Too many arguments!')

if __name__=='__main__':
    test()

1行和第2行是标准注释,第1行注释可以让这个hello.py文件直接在Unix/Linux/Mac上运行,第2行注释表示.py文件本身使用标准UTF-8编码;

4行是一个字符串,表示模块的文档注释,任何模块代码的第一个字符串都被视为模块的文档注释;

6行使用__author__变量把作者写进去,这样当你公开源代码后别人就可以瞻仰你的大名; 

import sys

导入sys模块后,我们就有了变量sys指向该模块(获取到名为sys的模块对象),利用sys这个变量,就可以访问sys模块的所有功能。sys模块有一个argv变量,用list存储了命令行的所有参数。

argv至少有一个元素,因为第一个参数永远是该.py文件的名称。

当我们在命令行运行hello模块文件时,Python解释器把一个特殊变量__name__置为__main__,而如果在其他地方导入该hello模块时,if判断将失败,

因此,这种if测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试。 

$ ./hello.py 
Hello, world
$ python3 hello.py 
Hello, world
$ python3
Python 3.5.2 (default, Nov 12 2018, 13:43:14) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import hello
>>> hello.test()
Hello, world

python交互环境导入时没有打印“Hello, world”,只有调用模块函数hello.test()才执行,方便模块导入。

作用域

在一个模块中,我们可能会定义很多函数和变量,但有的函数和变量我们希望给别人使用,有的函数和变量我们希望仅仅在模块内部使用。在Python中,是通过“_”前缀来实现的。

类似_xxx__xxx这样的函数或变量就是非公开的(private),不应该被直接引用,比如_abc__abc等。类似__xxx__这样的变量是特殊变量,可以被直接引用,但是有特殊用途,比如上面的__author____name__就是特殊变量,hello模块定义的文档注释也可以用特殊变量__doc__访问,我们自己的变量一般不要用这种变量名。

外部不需要引用的函数全部定义成private,只有外部需要引用的函数才定义为public

from方法

import math
print(math.pi)

from math import *
from math import pi
print(pi)

import和from-import区别

1. 调用模块属性的区别
    import 模块名
    模块名.xxx = 引用

    from 模块名 import *
    xxx = 拷贝  # 能修改属性值  

    函数,类... : "import 模块名""from 模块名 import *" 都是引用

2. 私有属性两种导入的区别
    # . 类中的私有属性
    # 本质做了一个名字重整
    class test()
      self.__name
    __name 名字重整成 _test__name

    from 模块 import * : 导入模块时,会跳过私有属性;
    import 模块 : 通过引用可以访问私有属性

明显区别:

from A import B在导入过程中,创建模块对象将模块对象的引用保存在本地作用域, 也就是说当前作用域有一个名字叫B的对象,locals()可以查看。

import A 在导入模块的过程 创建模块对象 将模块对象的引用保存在本地。

三、安装第三方模块

使用pip安装python模块。一般来说,第三方库都在python官网pypi.python.org网站注册。

要安装一个第三方库,必须先知道该库的名称,可以在官网或者pypi上搜索,比如Pillow的名称叫Pillow,因此,安装Pillow的命令就是:

pip install Pillow 

pip加速

配置pip阿里加速,添加 ~/.pip/pip.conf 文件,内容如下:

[global]
index-url = https://mirrors.aliyun.com/pypi/simple/
timeout = 6000
[install]
trusted-host = mirrors.aliyun.com 

windows下文件管理器搜索%APPDATA%,新建pip/pip.ini,内容同上。

模块搜索路径

默认情况下,Python解释器会搜索当前目录、所有已安装的内置模块和第三方模块,搜索路径存放在sys模块的path变量中:

>>> import sys
>>> sys.path
['', '/usr/lib/python35.zip', '/usr/lib/python3.5', '/usr/lib/python3.5/plat-x86_64-linux-gnu', '/usr/lib/python3.5/lib-dynload', 
'/home/wang/.local/lib/python3.5/site-packages', '/usr/local/lib/python3.5/dist-packages', '/usr/lib/python3/dist-packages'

如果我们要添加自己的搜索目录,有两种方法:

一是直接修改sys.path,添加要搜索的目录:

>>> import sys
>>> sys.path.append('/Users/michael/my_py_scripts')

这种方法是在运行时修改,运行结束后失效。

第二种方法是设置环境变量PYTHONPATH,该环境变量的内容会被自动添加到模块搜索路径中。设置方式与设置Path环境变量类似。注意只需要添加你自己的搜索路径,Python自己本身的搜索路径不受影响。


参考:廖雪峰 模块 使用模块 安装第三方模块

posted @ 2019-06-03 23:32  yuxi_o  阅读(975)  评论(0编辑  收藏  举报