————————————————异常————————————————–
异常
区分 异常和错误
产生异常
raise语句显示的抛出异常,BaseException类的子类或实例
Python解释器检测到异常并引发
异常捕获:
try:
待捕获异常的代码块
except [异常类型]:
异常的处理代码块
异常类及继承层次
BaseException
递归代码
def exc_hierarchy(exc=BaseException, level=-1):
name = exc.__name__
if level == -1:
print(name)
else:
print(“{} +– {}”.format(‘ ‘ * level, name))
for sub in exc.__subclasses__():
exc_hierarchy(sub, level+1)
所有内建异常类的基类 BaseException
SysemExit
sys.exit()
KeyboardInterrupt
Exception 内建的、非系统退出的、自定义的异常都继承它
SyntaxError 语法错误
ArithmeticError 算术错误
LookupError 映射异常 IndexError KeyError
自定义异常
class MyException(Exception):
pass
try:
raise MyException()
except MyExcetion:
print(‘catch the exception’)
except 可以捕获多个异常
从小到大 从具体到宽泛
finally子句 无论如何都会执行
清理、释放工作
异常传递:由内层到外层 进行捕获处理
#线程中测试异常
import threading
import time
def foo1():
return 1/0
def foo2():
time.sleep(5)
print(‘foo2 start’)
foo1()
print(‘foo2 stop’)
t = threading.Thread(target=foo2)
t.start()
while True:
time.sleep(1)
print(‘Everything OK’)
if t.is_alive():
print(‘alive’)
else:
print(‘dead’)
break
try嵌套:
由内向外传递和捕获
如果内层有finally且有return break 语句,异常就不向外层抛出
def foo():
try:
ret = 1/0
except KeyError as e:
print(e)
finally:
print(‘inner fin’)
return #异常被丢弃
try:
foo()
except:
print(‘outer catch’)
finally:
print(‘outer fin’)
异常的捕获时机
1、立即捕获
立刻返回明确的结果
def parse_int(s):
try:
return int(s)
except:
return 0
print(parse_int(‘s’))
2、边界捕获
封装产生了边界 最外层必须处理异常
else子句 没有异常则执行
标准模式:
try:
<语句> #运行别的代码
except <异常类>:
<语句> #捕获某种类型的异常
except <异常类> as <变量名>:
<语句> # 捕获某种异常的类型并获得对象
else:
<语句> #如果没有异常发生
finally:
<语句> #退出try时总会执行
————————————————模块化———————————————
模块化
代码组织方式:库、包、模块
Python: 模块module 源代码文件
包package, 包名同名的目录及相关文件
import module[.module] 必须是模块
import module[.module] as … 模块别名
部分导入
from…import…
from…import…as…
看名词空间或属性 dir()
from functools import wraps as wr, partial
from os.path import exists
getattr(os.path, ‘exists’)
from pathlib import path
导入顶级模块,其名称加入本地名词空间,并绑定到模块对象
导入非顶级模块,只将顶级模块名称加入名词空间,访问要限定名称,例如:os.path
自定义模块:.py文件就是一个模块
模块名(即文件名)命名规范同标识符:数字、字母、下划线,非数字开头,通常全小写。
使用sys.path查看模块搜索顺序
程序主目录–主程序脚本所在目录–环境变量PYTHONPATH设置的目录–标准库目录–自带的库模块目录
sys.modules是存储所有加载的模块的字典
模块运行
特殊变量 __name__
解释器初始化:会初始化sys.modules字典、创建builtins(全局函数、常量)模块、__main__模块、sys模块以及模块搜索路径sys.path
if __name__ == “__main__” :用途
1、功能测试:作为非主模块,测试模块里的函数、类
2、避免主模块变更副作用:未封装的代码被执行了
模块的属性
__file__ 源文件路径
__cached__ 编译后字节码文件路径
__spec__ 模块的规范
__name__ 模块名
__package__ 模块是包,同__name__; 否则,可以设置为顶级模块的空字符窜
包
特殊的模块
Pycharm —project—new—python package
代码写在 __init__.py中
模块目录和子文件 、子模块
导入子模块一定会加父模块,但导入父模块一定不会导入子模块
包目录之间只能使用.点作为间隔,表示层级关系
封装:模块、函数、类、变量
模块是命名空间,内部的顶层标识符都是它的属性,可以通过__dict__或dir(module)查看
包是特殊的模块,包含__path__属性
区分 from json import encoder 名词空间无json json.dump无法使用
import json.encoder 名词空间有json json.dump 可以使用
绝对导入
模块名称前不是.开头
去搜索路径中找
相对导入
只能包内使用,用from语句
. 当前目录
.. 上一级目录
… 上上一级
顶层模块中不要使用相对导入
访问控制
模块内的标识符:
普通变量、保护变量、私有变量、特殊变量,都没有被隐藏
控制导入的模块:
1、from xyx import *
模块编写尽量加入 __all__ 控制导入的模块,下划线开头模块、相对引用包的子模块也可以加入
2、from module import name1, name2
知道要导入的模块
模块变量的修改:注意其他使用影响
———————————————————–分发——————————————————
包管理–分发
发布和共享,目的为了复用。
官方仓库中心:Pypi(Python Package Index), https://pypi.python.org/pypi
主要工具
distutils: 使用setup.py来构建、安装包,2000年停止开发。
setuptools:使用ez_setup.py文件。支持egg的构建安装。提供查询、下载、安装、构建、发布、管理等包管理功能。
pip:从Python3.4开始直接包含在安装文件里。
wheel:二进制形式安装Python库,无需本地编译。
方法:
参考例子:
https://docs.python.org/3.5/distutils/setupscript.html
#!/usr/bin/env python
from distutils.core import setup
setup(name=’Distutils’,
version=’1.0′,
description=’Python Distribution Utilities’,
author=’Greg Ward’,
author_email=’gward@python.net’,
url=’https://www.python.org/sigs/distutils-sig/’,
packages=[‘distutils’, ‘distutils.command’],
)
建包:$python setup.py build
注意每个层级的包都要打包
安装:$python setup.py install
分发:$python setup.py sdist
$python setup.py bdist_wininst #windows下的分发包
$python setup.py bdist_rpm #打包成rpm
——————————————–插件化开发——————————————–
插件化开发:
接口:约定规范,暴露功能, api
插件:加载到系统中,提供或增强某功能
核心代码示例:
importlib.import_module()
#importlib.import_module(name, package=None)
#主程序模块test.py
import importlib
def plugin_load(plugin_name:str, sep=”:”):
m, _, c = plugin_name.partition(sep)
mod = importlib.import_module(m)
cls = getattr(mod, c)
return cls()
if __name__ == “__main__”:
#装载插件
a = plugin_load(“test1:A”)
a.showme()
———————————————-插槽和反向—————————————-
基础知识补充:
__slots__ 插槽,规定了实例的属性,实例无需创建__dict__存储属性,从而在数据规模较大时节省内存。而且,在类被继承时,它不会继承。
区分 NotImplemented, 单值,是NotImplementedType类的实例
NotImplementedError 是类型,是异常, 返回type
运算符重载的反向方法:例如 __radd__
本文来自投稿,不代表Linux运维部落立场,如若转载,请注明出处:http://www.178linux.com/99154