一、包管理
-
Pypi(Python package Index):公共的模块存储中心,https://pypi.python.org/pypi
-
主要工具:distutils、setuptools、pip、wheel
-
使用 setup.py 打包在项目的根目录下面创建 setup.py 文件在终端中运行 python setup.py –help[cmd1 cmd2] 可以查看命令的帮助from distutils.core import setupsetup(name=’myname’,version=’0.1.1′,description=’magedu module’, # 描述信息author=’Pang Hao’,author_email=’panghao@python.net‘,url=’https://www.python.org/sigs/distutils-sig/‘, # 包的主页,可以不写packages=[‘m’] # 指定 m,就会把 m 所有的非目录子模块打包# packages=[‘m’, ‘m.m1.m2.m3’] # 逐级建立目录,但是只把 m 的所有非目录子模块打包, 把 m.m1.m2.m3 打包)python setup.py build # 创建一个 build 目录,会在项目目录下多了 build 目录,有一个 lib 子目录,lib 下就是模块 m 的目录了,m 目录下的 *.py 文件被复制了,但是子目录没有被复制
-
python setup.py install # 如果没有 build ,会先 build 编译,然后安装,也可以在 pip 里面看到
-
python setup.py sdist # 创建源代码的分发包,会产生一个 dist 目录,里面生成一个带版本号的压缩包。在其他地方解压缩这个文件,里面有 setup.py,就可以使用 python setup.py install 安装,也可以使用 pip install m-0.1.0.zip 直接使用 pip 安装这个压缩包python setup.py bdist_wininst # 制作 windows 下的分发包python setup.py bdist_rpm # 打包成 rpm
-
wheel 包pip install wheelfrom setuptools import setupsetup(name=’myname’,version=’0.1.1′,description=’magedu module’, # 描述信息author=’Pang Hao’,author_email=’panghao@python.net‘,url=’https://www.python.org/sigs/distutils-sig/‘, # 包的主页,可以不写packages=[‘m’] # 指定 m,就会把 m 所有的非目录子模块打包)
二、异常处理
-
错误和异常:在高级编程语言中,一般都有错误和异常的概念,异常是可以捕获,并被处理的,但是错误是不能被捕获的。
-
产生异常:raise 语句显式的抛出异常;Python 解释器自己检测到异常并引发它;程序会在异常抛出的地方中断执行,如果不捕获,就会提前结束程序
-
raise 语句raise 后什么都没有,表示抛出最近一个被激活的异常,如果没有被激活的异常,则抛类型异常,这种方式很少用raise 后要求应该是 BaseException 类的子类或实例,如果是类,将被无参实例化
-
异常的捕获try:待捕获异常的代码块except [异常类型]:异常的处理代码块
-
异常类及继承层次BaseExceptionSystemExitKeyboardInterruptGeneratorExitExceptionRuntimeErrorRecursionErrorMemoryErrorNameErrorStopIterationStopAsyncIterationArithmeticErrorFloatingPointErrorOverflowErrorZeroDivisionErrorLookupErrorIndexErrorKeyErrorSyntaxErrorOSErrorBlockingIOErrorChildProcessErrorConnectionErrorBrokenPipeErrorConnectionAbortedErrorConnectionRefusedErrorConnectionResetErrorFileExistsErrorFileNotFoundErrorInterruptedErrorIsADirectoryErrorNotADirectoryErrorPermissionErrorProcessLookupErrorTimeoutError
-
BaseException:所有内建异常类的基类是 BaseExceptionSystemExit:sys.exit() 函数引发的异常,异常捕获处理,就直接交给 Python 解释器,解释器退出Exception:所有内建的、非系统退出的异常的基类,自定义异常应该继承自它SyntaxError:语法错误,Python 将这种错误也归到 Exception 下的子类,但是这种错误是不可捕获的ArithmeticError:所有算术计算引发的异常,其子类有除零异常LookupError:使用映射的键或序列的索引无效时引发的异常的基类,比如 IndexError、KeyError自定义异常:从 Exception 继承的类class MyException(Exception):passtry:raise MyException()except MyException:print(‘Catch the exception’)
-
捕获规则捕获是从上到下依次比较,如果匹配,则执行匹配的 except 语句块如果被一个 except 语句捕获,其他 except 语句就不会再次捕获了如果没有任何一个 except 语句捕获到这个异常,则该异常向外抛出捕获的原则:从小到大,从具体到宽泛
-
finally 子句:最终,即最后一定要执行的,try…finally 语句块中,不管是否发生了异常,都要执行 finally 的部分简单的说,函数的返回值取决于最后一个执行的 return 语句,而 finally 则是 try…finally 中最后执行的语句块
-
try 嵌套:内部捕获不到异常,会向外层传递异常,但是如果内层有 finally 且有 return、break 语句,则异常就不会继续向外抛出
-
没有任何异常发生,则执行 else 子句
-
总结try:<语句> # 运行别的代码except <异常类>:<语句> # 捕获某种类型的异常except <异常类> as <变量名>:<语句> # 捕获某种类型的异常并获得对象else:<语句> # 如果没有异常发生finally:<语句> # 退出 try 时总会执行如果 try 中语句执行时发生异常,搜索 except 子句,并执行第一个匹配该异常的 except 子句;如果 try 中语句执行时发生异常,却没有匹配的 except 字句,异常将被递交到外层的 try,如果外层不处理这个异常,异常将继续向外层传递。如果都不处理该异常,则会传递到最外层,如果还没有处理,就终止异常所在的线程;如果在 try 执行时没有发生异常,将执行 else 子句中的语句;无论 try 中是否发生异常,finally 子句最终都会执行
-
层次结构代码实现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)exc_hierarchy()
-
NotImplemented 是个值,单值,是 NotImplementedType 类的实例NotImplementedError 是类型,是异常,返回 type不能用 raise NotImplemented,用过用 raise NotImplementedError
三、插件化开发
-
动态导入:运行时,根据用户需求(提供字符串),找到模块的资源动态加载起来
-
__import__(name, globals=None, locals=None, fromlist=(), level=0)name:模块名import 语句本质上就是调用这个函数,但是不鼓励直接使用它,建议使用 importlib.import_module( )sys = __import__(‘sys’) 等价于 import sys
-
importlib.import_module(name, package=None):支持绝对导入和相对导入,如果是相对导入,package 必须设置
-
插件化编程核心代码实现# test1.pyclass A:def showme(self):print(‘I am A’)# 主程序模块 tets.pyimport importlibdef 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.show
-
依赖的技术反射:运行时获取类型的信息,可以动态维护类型数据动态 import:推荐使用 importlib 模块,实现动态 import 模块的能力多线程:可以开启一个线程,等待用户输入,从而加载指定名称的模块
-
加载的时机程序启动时:像 pycharm 这样的工具,需要很多组件,这些组件可能是插件,启动的时候扫描固定的目录,加载插件程序运行中:程序运行过程中,接受用户指令或请求,启动相应的插件两种方式各有利弊,如果插件过多,会导致程序启动很慢,如果用户需要时再加载,插件太大或者依赖多,插件也会启动慢。所以先加载必须的,常用的插件,其他插件使用时,发现需要,动态载入。
-
接口和插件的区别接口往往是暴露出来的功能,例如模块提供的函数或方法,加载模块后调用这些函数完后功能。接口也是一种规范,它约定了必须实现的功能(必须提供某名称的函数),但是不关心怎么实现这个功能。插件是把模块加载到系统中,运行它,增强当前系统功能,或者提供系统不具备的功能,往往插件技术应用在框架设计中,系统本身设计简单化、轻量级,实现基本功能后,其他功能通过插件加入进来,方便扩展。
本文来自投稿,不代表Linux运维部落立场,如若转载,请注明出处:http://www.178linux.com/99095