文章目录

  • 一、模块就是程序
  • 二、模块的搜索路径(sys 模块的使用)
  • 三、包
  • 四、模块导入时与运行时
  • 五、pip 包管理器的使用及其下载源的更改
  • 1、pip 包管理器的使用
  • 2、pip 下载源的更改
  • 六、默认 py2 和 py3 的切换
  • [七、Python 常用标准库](https://docs.python.org/2/library/)
  • [八、Python 常用第三方库(博客总结)](https://awesome-python.com/)
  • 九、参考资料



一、模块就是程序

  • 封装性
  • 容器:例如list tuple string set dict等,这些是对数据的封装。
  • 函数:对语句的封装,是可以实现一项或多项功能的一段程序
  • 类:对方法和属性的封装,也就是对函数和数据的封装。
  • 模块:是可以实现一项或多项功能的程序块。我们保存的每一个.py结尾的文件,都是一个独立的模块,其中,文件名 = 模块名
  • 导入模块的方法
  • import 模块名
  • import 模块名 as 新名字
  • from 模块名 import 函数名/类名:大型项目中应尽量避免使用此方法,除非你非常确定不会造成命名冲突;它有一个好处就是可直接使用function()而不用加module.function()
  • 模块中变量、函数以及类的属性和方法的调用
  • module.variable
  • module.function()
  • module.class.variable
module.class.method() 
# TypeError: unbound method hi_somebody() must be called with hi instance as first argument (got str instance instead)

# 不能直接使用模块中类中的方法,要先将类进行实例化
ins = module.class()
ins.variable
ins.method()
  • 模块的 __name__属性
  • 所有程序模块都有一个__name__属性,__name__的值取决于如何应用模块
  • 作为独立程序运行的时候,__name__属性的值是'__main__'(将顺序执行if __name__ == '__main__': 后面的代码,这样我们就可以做单元测试来检验模块中内容的正确性)
  • 作为模块导入的时候,__name__属性的值就是该模块的名字了(if __name__ == '__main__': 后面的代码将不执行)
  • 使用模块有什么好处
  • 大大提高了代码的可维护性
  • 编写代码不必从零开始。当一个模块编写完毕,就可以被其他地方引用 (代码重用)
  • 可以避免函数名和变量名冲突,相同名字的函数和变量完全可以分别存在不同的模块中
  • Python2 使用 Python3 的特性
  • Python 提供了__future__模块,把下一个新版本的特性导入到当前版本,于是我们就可以在当前版本中测试一些新版本的特性
  • eg:from __future__ import division

二、模块的搜索路径(sys 模块的使用)

  • 模块默认搜索路径:
  • 程序当前目录
  • 标准库的安装路径(eg:/home/manzp/anaconda2/lib 各种 py 模块文件)
  • 操作系统环境变量 PYTHONPATH 指向的路径
  • 获取及添加模块搜索路径的方法:
import sys

# 一、获取模块搜索路径
sys.path
['',  # 当前路径
 '/home/manzp/anaconda2/bin',  # 可执行文件
 '/home/manzp/caffe_ssd/caffe/python',  # PYTHONPATH
 '/home/manzp/anaconda2/lib/python27.zip',
 '/home/manzp/anaconda2/lib/python2.7',
 '/home/manzp/anaconda2/lib/python2.7/plat-linux2',
 '/home/manzp/anaconda2/lib/python2.7/lib-tk',
 '/home/manzp/anaconda2/lib/python2.7/lib-old',
 '/home/manzp/anaconda2/lib/python2.7/lib-dynload',
 '/home/manzp/anaconda2/lib/python2.7/site-packages',  # 第三方库,lib 下为系统库
 '/home/manzp/anaconda2/lib/python2.7/site-packages/smop-0.41-py2.7.egg',
 '/home/manzp/anaconda2/lib/python2.7/site-packages',
 '/home/manzp/anaconda2/lib/python2.7/site-packages/IPython/extensions',
 '/home/manzp/.ipython']

# 二、添加模块搜索路径
# 1、加入的是临时搜索路径,程序退出后失效(主程序代码中加入即可,其它代码就能找到,直接使用即可)
sys.path.append('module_path')    
sys.path.insert(0, 'module_path') # 定义搜索路径的优先顺序,序号从 0 开始,表示最大优先级
export PYTHONPATH=/home/manzp/caffe_ssd/caffe/python  # bash 中执行

# 2、在系统的环境变量里进行配置,使其永久生效
sudo vim ~/.bashrc   # 或者 sudo vim /etc/profile 
export PYTHONPATH=/home/manzp/caffe_ssd/caffe/python:$PYTHONPATH 
source ~/.bashrc 	 # 或者 source /etc/profile
  • sys 模块的 argv 变量的用法
  • sys 模块有一个 argv(argument values) 变量,用 list 存储了命令行的所有参数
  • argv 至少有一个元素,因为第一个元素永远都是.py文件的名称。
$ python solve.py 0    # 命令行语句
# 获得argv变量的值
sys.argv = ['solve.py', '0']
sys.argv[0] = 'solve.py'
sys.argv[1] = '0'
  • 使用 sys.stdout.write() 和 \r 实现进度条
  • sys.stdout 的形式就是 print 的一种默认输出格式,只不过输出不会自动换行
  • \r 回车到本行首,可刷新输出
for i, image_example in enumerate(dataset):
    if (i + 1) % 100 == 0:
        sys.stdout.write('\r>> %d/%d images has been converted' % (i + 1, len(dataset)))
    
    sys.stdout.flush()  # 强制刷新缓冲区,立刻进行打印

三、包

  1. 包的定义及优点
  • Python 把同类的模块放在一个文件夹中统一管理,这个文件夹称之为一个
  • 如果把所有模块都放在一起显然不好管理,并且有命名冲突的可能。
  • 包其实就是把模块分门别类地存放在不同的文件夹,然后把各个文件夹的位置告诉Python。
  • Python 的包是按目录来组织模块的,也可以有多级目录,组成多级层次的包结构。
  1. 包的创建
  • 创建一个文件夹,用于存放相关的模块,文件夹的名字即为包的名字
  • 在文件夹中创建一个__init__.py的模块文件,内容可以为空(普通文件夹和包的区别)或自定义一些内容;导入一个包的时候,会首先执行这个包中 __init__.py 中的代码
  • 将相关模块放入文件夹中
  • __init__.py 实现 包级别模块的预加载
  • __init__ 保持为空文件,他就只是标记目录为 python 中的包,导入包中模块的函数时需要使用 包.模块 具体指定那个包中的那个模块。因为需要的函数在包中看不到,只在具体模块中可见
  • __init__ 文件中导入以后,他将成为包级别的内容,也就是在包中可见,简化了在其它地方的导入
  • __init__.py 实现包变量的预定义:在 __init__ 中使用 __all__ 可以定义 from pkg import *“*” 包含的内容,不在其中的函数或类在包级别对外不可见,在模块级别还是可见的
  • __init__.py 实现 多级包级别别模块的预加载:如下图所示,__all__ 里面的函数和类在 models 包级别可见
  • 在一级包的初始化中:导入二级包名下的所有模块,这样在一级包就能看到二级包下面的所有模块
  • 在二级包的初始化中:导入模块中的所有类和函数,这样在一级包就能看到二级包下面的所有模块中的函数和类
  • 在具体模块中:使用 __all__ 定义包级别可见的类、函数
  • 使用示例:from models import resnet18
  1. 包的管理
  • 详见博客: 使用 Anaconda 进行包和环境的管理
  1. 包的存放路径及包中模块的导入与调用
  • 包的存放
  • 如果不想把相关的模块文件放在所创建的文件夹中,那么最好的选择就是:放在 site-packages # 默认模块文件存放路径文件夹里,因为它就是用来存放你的模块文件的。
  • sys.path.append('package_path'):只是在本程序运行时生效,运行结束后失效。
  • 将包的存放路径加入用户系统环境变量中的PYTHONPYTH中去,这样在任何位置都可以调用包了,极力推荐!
vim .bashrc  
export PYTHONPATH=~/caffe/examples(/package_name)  # 只需把包的上一级目录加入PYTHONPATH即可,括号中的内容要去掉,这里写上只为了让大家知道包`package_name`在`~/caffe/examples`目录下。 
source .bashrc             # 保存后使其立即生效
  • 包中模块的导入
  • import 包名.模块名
  • import 包名.模块名 as 新名字
  • from 包名 import 模块名
  • from 包名.模块名 import 函数名:模块级别可见
  • from 包名 import 函数名:包级别可见
  • importlib 用法
import importlib

# 一、importlib.import_module(name, package=None),函数有如下两种调用方式:
# - 绝对导入,name为完整路径str,package为None。
# - 相对导入,package需指定对应包位置。

# 与 import time 效果一样
time = importlib.import_module('time')
print(time.time())

# 与 import os.path as path 效果一样
path = importlib.import_module('os.path')
path.join('a', 'b')  # results: 'a/b'

# 相对引入, 一级目录,与 import os.path as path 效果一样
path = importlib.import_module('.path', package='os')
path.join('a', 'b')  # results: 'a/b'


# 二、importlib 的强大之处是将 import 语句中写死的字面值改成了 import_module 函数中的参数
# 因此可以通过修改参数在外部用变量来控制实际 import 的包或者模块,大大地增加了灵活性

# 设计一个深度学习工具库,里面包含了N个网络模型(ResNet50, HRNet, MobileNet等等),每个模型的实现都有一个
# load_model 的函数。由于计算设备的性能不同,需要调用的网络结构也会变化,我们需要根据外部传入的参数来判断实际 load 哪一个模型
# 采用 import语句 + if-else 判断也能完成这个需求,但此写法冗余,且新增模型时需要修改调用处的代码,添加对应的import语句
def run(model_name, input):
    if model_name == 'resnet_50':
        from resnet_50.model import load_model
    elif model_name == 'hrnet':
        from hrnet.model import load_model
    elif model_name == 'moblienet':
        from mobilenet.model import load_model

    model = load_model()
    output = model(input)
    return output

# 采用 importlib 大大简化代码
def run(model_name, input):
    load_model = importlib.import_module('load_model', package='{}.model'.format(model_name))
    model = load_model()
    output = model(input)
    return output



# 从包级别动态的导入配置文件中的类和函数(!!!)
package = importlib.import_module(cfg.package_name)  # 动态导入指定名称的包
function = getattr(package, cfg.function_name)  # 动态获取包中指定名称的函数对象
result = function()  # 调用被导入的函数

# 直接从顶层包级别动态的使用模块中的类或函数:需要在各级包中提前导入
import models
self.model = eval('models.' + self.cfg.MODEL.NAME +'(self.cfg.MODEL.NUM_CLASSES, self.cfg.MODEL.PATH)')
  • 包中模块的变量、函数以及类的属性和方法的调用
  • package.module.variable
  • package.module.function()
  • package.module.class.variable
package.module.class.method() 
# TypeError: unbound method hi_somebody() must be called with hi instance as first argument (got str instance instead)

# 不能直接使用包中模块的类的方法,要先将类进行实例化
ins = package.module.class()
ins.variable
ins.method()

四、模块导入时与运行时

  • 导入时或运行时 模块中的顶级代码(打印、变量赋值、类的定义等)及 类中的顶级代码(打印、变量赋值、函数的定义等)都会执行
  • 装饰器在导⼊时或运行时 立即执行函数的装饰器,优先级⽐函数⾼,⽽ 类的装饰器
  • 模块中的函数或者是类(对象)中的⽅法(除了装饰器),仅仅在 调⽤时(运行时)
  • 无论在导入时还是运行时,模块只会导⼊⼀次(最先导入的),解释器如果发现模块已经被导⼊,则跳过,继续向后执⾏(避免写出互相导⼊的死循环代码)
-------------------------------------------------
# import_runtime.py start
-------------------------------------------------
# 这里是模块的顶级代码(模块导入/运行时会运行)
print("module {} start.".format(__name__)) 
y = 12
print('y is {}'.format(y))

# Class 定义是模块的顶级代码(模块导入/运行时会运行)
class ClassX(): 
    # 这里是类的顶级代码(模块导入/运行时会运行)
    x = 5  
    print('x is {}'.format(x))
    print("ClassX body start.") 

    def __init__(self):  				
        print("ClassX __init__")		

    def __del__(self):
        print("ClassX __del__")

    def method(self):
        print("ClassX method.")


def func_x():  			
    print("func_x.")   

# 类装饰器
def deco_class(cls):
    print("decorator for class.")
    print("decorate {}.".format(cls.__name__))
    return cls

# 函数装饰器
def deco_func(func):
    print("decorator for function.")
    print("decorate {}.".format(func.__name__))
    return func


@deco_class  # 这里是类装饰器(模块导入/运行时会运行)
class ClassY():
    print("ClassY body start.")

    def __init__(self):
        print("ClassY __init__.")

    def __del__(self):
        print("ClassY __del__.")

    @deco_func  # 这里是函数装饰器(模块导入/运行时会运行)
    def method(self):
        print("ClassY method.")

    @deco_class  # 这里是类装饰器(模块导入/运行时会运行)
    class ClassZ():
        print("ClassZ body start.")


@deco_func  # 这里是函数装饰器(模块导入/运行时会运行)
def func_y():
    print("function func_y.")


if __name__ == "__main__":
    # pass
    x = ClassX()
    x.method()
    func_x()
    y = ClassY()
    y.method()
    func_y()
print("module {} end.".format(__name__))
-------------------------------------------------
# import_runtime.py end
-------------------------------------------------


module import_runtime start.
y is 12
x is 5
ClassX body start.
ClassY body start.
decorator for function.
decorate method.
ClassZ body start.
decorator for class.
decorate ClassZ.
decorator for class.
decorate ClassY.
decorator for function.
decorate func_y.
module import_runtime end.
-------------------------------------------------
# 上面输出结果为导入时(__main__ 换成模块名 import_runtime )的输出
-------------------------------------------------
module __main__ start.
y is 12
x is 5
ClassX body start.
ClassY body start.
decorator for function.
decorate method.
ClassZ body start.
decorator for class.
decorate ClassZ.
decorator for class.
decorate ClassY.
decorator for function.
decorate func_y.

ClassX __init__
ClassX method.
func_x.
ClassY __init__.
ClassY method.
function func_y.
module __main__ end.
ClassX __del__
ClassY __del__.
-------------------------------------------------
# 上面输出结果为运行时(__main__)的输出
# 运行时 = 导入时+main+析构,模块的顶级代码都会执行
-------------------------------------------------

五、pip 包管理器的使用及其下载源的更改

1、pip 包管理器的使用

  • PyPI(Python Package Index)是 python 官方的第三方库的仓库,PyPI 推荐使用 pip 包管理器来下载第三方库
  • 安装 pip:sudo apt-get install python-pip,安装 pip3:sudo apt-get install python3-pip
# pip 使用格式
pip <command> [options] package_name

# 安装指定版本的包
pip install package_name==1.9.2

# 更新指定的包
pip install --upgrade package_name

# 卸载指定的包
pip uninstall package_name

# 查看所安装包的详细信息
pip show package_name

# 查看所有安装的包
pip list

# 查看帮助
pip --help

2、pip 下载源的更改

# 升级 pip
pip3 install --upgrade pip
eg:pip3 install opencv-python


# 国内常用的镜像
https://pypi.douban.com/simple/            # 豆瓣
http://mirrors.aliyun.com/pypi/simple/    # 阿里
https://pypi.tuna.tsinghua.edu.cn/simple  # 清华
https://pypi.mirrors.ustc.edu.cn/simple/   # 中国科学技术大学
http://pypi.hustunique.com/simple/ 		  # 华中理工大学


# 1、临时使用,添加 “-i” 或 “--index” 参数
pip install -i https://pypi.douban.com/simple/ flask --trusted-host pypi.douban.com
pip install --extra-index-url https://pypi.douban.com/simple/ flask  # 报错时可尝试加 --extra-index-url
pip3 install --ignore-installed PyYAML -i https://pypi.tuna.tsinghua.edu.cn/simple 
# PyYAML 安装,报错无法卸载旧版本,尝试加参数 --ignore-installed 或 --force-reinstall 解决

# 2、linux 下永久生效的配置方法
cd $HOME  
mkdir .pip  
cd .pip
sudo vim pip.conf  

# 在里面添加,trusted-host 选项为了避免麻烦是必须的,否则使用的时候会提示不受信任  
[global]
index-url=https://pypi.tuna.tsinghua.edu.cn/simple

[install]
trusted-host=pypi.tuna.tsinghua.edu.cn 
disable-pip-version-check=true
timeout = 6000 


# 3、window 下永久生效的配置方法
# a、进入如下目录(没有此目录或文件就自己创建下)
C:\Users\username\AppData\Local\pip
或
C:\Users\username\pip

# b、创建 “pip.ini” 文件(注意:以UTF-8 无BOM格式编码),添加如下内容
[global]
index-url=https://pypi.tuna.tsinghua.edu.cn/simple

[install]
trusted-host=pypi.tuna.tsinghua.edu.cn 
disable-pip-version-check=true
timeout = 6000

六、默认 py2 和 py3 的切换

# 1、Create list of alternatives for python
sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.5 2

# 2、Check the python list
update-alternatives --list python

# 3、update alternative to select required python version
sudo update-alternatives --config python

python 模块Client Python 模块,类,方法,函数_常用第三方库


七、Python 常用标准库

文件相关(os、os.path、 glob模块)、存储对象(pickle、cPickle模块)

记录日志(logging 模块)

时间与日期(time&timeit 模块)

正则表达式(re 模块)

数学、随机数生成等(使用numpy 或 scipy 等第三方库)

循环器(itertools)

数据库(sqlite3)

线程同步(threading包)

多进程初步(multiprocessing包)


八、Python 常用第三方库(博客总结)

  • Anaconda:包管理
  • Ipython & Jupyter Notebook:快速验证思路、分享和演示
  • OpenCV:图像处理
  • Numpy:快速向量化运算
  • Scipy:科学计算
  • Pandas:序列化数据的分析处理
  • Matplotlib:类似 Matlab 的画图工具
  • Scikits:scikits-learn 机器学习和 scikits-image 图像处理
  • Xgboost

九、参考资料

1、python文件目录下的__init__文件2、python importlib 用法小结