异常、模块、分发、插件化开发、插槽和反向等

原创 社长  2019-08-24 14:23:13  阅读 76 次 评论 0 条
重庆专业seo
摘要:

————————————————异常————————————————–异常区分 异常和错误产生异常raise语句显示的抛出异常,BaseException类的子类或实例Python解释器检测到异常并引发异常捕获:try:待捕获异常的代码块except [异常类型]:异常的处理代码块异常类及继承层次BaseException递归代码def exc_hierarchy(exc=BaseException, level=-1):name = exc.__name__if level == -1:pri

————————————————异常————————————————–

异常

区分 异常和错误

产生异常

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__


本文地址:http://dxf6.com/post/387.html
版权声明:本文为原创文章,版权归 社长 所有,欢迎分享本文,转载请保留出处!
重庆专业seo
数据湾

发表评论


表情

还没有留言,还不快点抢沙发?