異常處理html
異常Exceptionpython
產生異常編程
異常的捕獲模塊化
異常類及繼承層次函數
BaseException及子類工具
執行!
Exception及子類測試
--ui
自定義異常url
異常的捕獲spa
as子句
finally子句
finally執行時機
異常的傳遞
# Author: Baozi #-*- codeing:utf-8 -*- #線程中測試異常 import threading import time def foo1(): return 1/0 def foo2(): time.sleep(3)#3秒後拋出異常 print('foo2 start') foo1() print('foo2 stop') t = threading.Thread(target=foo2) t.start() print('t-->starting') while True: time.sleep(1) print('Everything OK') if t.is_alive(): print('alive') else: print('dead')
try嵌套
try: try: ret = 1/0 except KeyError as e: print(e) else: print('OK') finally: print('inner fin') except: print('outer catch') finally: print('outer fin') #輸出以下: inner fin outer catch outer fin
內部捕獲不到異常,會向外層傳遞異常
可是若是內層有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') #輸出以下: inner fin outer fin
異常的捕獲機制
1.當即捕獲
def parse_int(s): try: return int(s) except: return 0 print(parse_int('sss'))
2邊界捕獲
else子句
try: ret = 1*0 except ArithmeticError as e: print(e) else: print('ok') finally: print('fin')
總結
try的工做原理
模塊化
導入語句
單獨運行下面例子,體會區別
總結
from語句
總結
自定義模塊
#test1.py文件 print("This is test1 module") class A: def showmodule(self): print("{}.a = {}".format(self.__module__,self)) print(self.__class__.__name__) a = A() a.showmodule() #輸出以下: This is test1 module __main__.a = <__main__.A object at 0x00000000028E5630> A #test2.py文件 import test1 a = test1.A() a.showmodule() #test3.py文件 from test1 import A as cls a = cls() a.showmodule() #test2.py和test3.py文件輸出以下: This is test1 module test1.a = <test1.A object at 0x00000000029C2F98> A test1.a = <test1.A object at 0x0000000001DC5518> A
自定義模塊命名規範
模塊搜索順序
import sys for i in sys.path: print(i) #輸出以下: F:\code_python_urllib_demo\Python全棧開發--異常及模塊 F:\code_python_urllib_demo D:\Anaconda3\python36.zip D:\Anaconda3\DLLs D:\Anaconda3\lib D:\Anaconda3 D:\Anaconda3\lib\site-packages D:\Anaconda3\lib\site-packages\Sphinx-1.5.6-py3.6.egg D:\Anaconda3\lib\site-packages\pip-9.0.1-py3.6.egg D:\Anaconda3\lib\site-packages\win32 D:\Anaconda3\lib\site-packages\win32\lib D:\Anaconda3\lib\site-packages\Pythonwin D:\Anaconda3\lib\site-packages\setuptools-27.2.0-py3.6.egg D:\pycharm\PyCharm 2017.3.4\helpers\pycharm_matplotlib_backend
模塊的重複導入
#test1.py文件 print("This is test1 module") class A: def showmodule(self): print("{}.a = {}".format(self.__module__,self)) print(self.__class__.__name__) a = A() a.showmodule() #test2.py文件 import test1 print('local module') import test1
模塊的運行
#test1.py文件 import test2 #test2.py文件 #判斷模塊是否以程序的方式運行 if __name__ == '__main__': print('in __main__')#程序的方式運行 else: print('in import module')#模塊導入的方式運行
if __name__ == '__main__':用途
模塊的屬性
包
import m print(m) print(type(m)) print(dir(m))#沒有__file__ #輸出以下: <module 'm' (namespace)> <class 'module'> ['__doc__', '__loader__', '__name__', '__package__', '__path__', '__spec__']
子模塊
#注意查看模塊的加載,當前名詞空間 import m # import m.m1 # from m import m1 # from m.m2 import m21 # import m.m2.m21 print(dir()) import sys print(sorted(sys.modules.keys()))
模塊和包的總結
絕對導入、相對導入
絕對導入
相對導入
訪問控制
下劃線開頭的模塊名
模塊內的標識符
#xyz.py文件 print(__name__) A = 5 _B = 6 __C = 7 __my__ = 8 #test.py文件 import xyz import sys print(dir())#['__annotations__',..., 'sys', 'xyz'] print(xyz.A,xyz._B,xyz.__C,xyz.__my__)#5 6 7 8
from語句
#修改test.py文件 from xyz import A,_B as B,__my__,__C as C import sys#xyz print(dir())#['A', 'B', 'C', '__annotations__', ...,'__my__',..., '__spec__', 'sys'] print(A,B,__my__,C)#5 6 8 7
from ... import * 和 __all__
使用from ... import * 導入
#修改test.py文件 from xyz import * import sys print(dir())#['A', ... , 'sys'] print(locals()['A']) print(sorted(locals().keys()))#['A', ... , 'sys'] A = 55 print(locals()['A'])
使用 __all__
#修改xyz.py文件 __all__ = ["X","Y"] print(__name__) A = 5 _B = 6 __C = 7 __my__ = 8 X = 10 Y = 20 #修改test.py文件 from xyz import * import sys # print(sorted(sys.modules.keys())) print(dir())#['A', ... , 'sys'] print(locals()['X'])#10 print(locals()['Y'])#20
#修改xyz.py文件 __all__ = ["X","Y","_B","__C"] print(__name__) A = 5 _B = 6 __C = 7 __my__ = 8 X = 10 Y = 20 #修改test.py文件 from xyz import * import sys # print(sorted(sys.modules.keys())) print(dir())#['A', ... , 'sys'] print(locals()['X'])#10 print(locals()['Y'])#20 print(locals()['_B'])#6 print(locals()['__C'])#7
包和子模塊
#__init.py文件中 print(__name__) x = 1 #m1.py文件中 print(__name__) y = 5 #test.py文件中 #如何訪問到m1.py中的變量m1 #訪問到m.m1的變量y的幾種實現 #方法1,直接導入m1模塊 import m.m1 print(dir())#['__annotations__', ... , 'm'] print(m.m1.y) #方法2,直接導入m.m1的屬性y from m.m1 import y print(dir())#['__annotations__', ... , 'y'] print(y) #方法3,from m import * #該方法導入後,沒法看到子模塊m1,沒法訪問y #在__init__.py增長__all__ = ['x','m1'],使用__all__提供導出的名稱 from m import * print(dir())#['__annotations__' ,... , 'm1', 'x'] print(m1.y) #方法4,不使用__all__ #在__init.py增長from . import m1 from m import * print(dir())#['__annotations__', ... , 'm1', 'x'] print(m1.y)
#__init.py文件 print(__name__) x = 1 from .m1 import y as _z print(dir())
總結
模塊變量的修改
#xyz.py文件 print(__name__) X = 10 #test2.py文件 import xyz print(xyz.X) #test.py文件 import xyz print(xyz.X) xyz.X = 50 import test2 #運行test.py文件輸出以下: xyz 10 50
模塊化高級內容
包管理
主要工具
distutils
setuptools
pip
wheel
使用setup.py打包
https://docs.python.org/3.5/distutils/setupscript.html
from distutils.core import setup #導入setup函數並傳參 setup( name = 'm', description = 'Python test m', author = 'chengyu', author_email = '867920363@qq.com', packages = ['m'] # packages = ['m','m.m1','m.m2','m.m2.m21'] ) #name 名字 #version 版本 #packages=[] 打包列表 #packages=['m'] 指定m,就會把m全部的非目錄子模塊打包 #['m','m.m1.m2.m3'] 逐級創建目錄,可是隻把m的全部非目錄子模塊打包,把m.m1.m2.m3打包 #description 描述信息 #author 做者 #author_email 做者郵件 #url 包的主頁,能夠不寫
build命令,編譯
install命令,安裝
install會安裝到site-packages路徑下。
sdist命令,分發
插件化開發
動態導入
1.內建函數__import__()
#主程序模塊test.py文件 if __name__ == '__main__': mod = __import__('test2') cls = getattr(mod,'A') cls().showme() #test2.py文件 class A: def showme(self): print('I am A')
importlib.import_module()
#test2.py文件 class A: def showme(self): print('I am A') #主程序模塊test.py import importlib def plugin_load(plugin_name:str,seq=":"): m,_,c = plugin_name.partition(seq) mod = importlib.import_module(m) cls = getattr(mod,c) return cls() if __name__ == '__main__': #裝載插件 a = plugin_load('test2:A') a.showme()
插件化編程技術
依賴的技術
加載的時機
應用
1、__slots__
問題的引出
class A: X = 1 def __init__(self): self.y = 5 self.z = 6 def show(self): print(self.X,self.y,self.z) a = A() print(A.__dict__) print(a.__dict__)
class A: X = 1 # __slots__ = ('y','z')#元組 # __slots__ = ['y','z']#能夠 # __slots__ = 'y','z'#能夠 __slots__ = 'y'#能夠 def __init__(self): self.y = 5 # self.z = 6 def show(self): # print(self.X,self.y,self.z) print(self.X,self.y) a = A() print(A.__dict__) # print(a.__dict__) print(a.__slots__)
繼承
class A: X = 1 __slots__ = ('y','z')#元組 def __init__(self): self.y = 5 def show(self): print(self.X,self.y) a = A() a.show() print(A.__dict__) print(a.__slots__) class B(A): pass print('B',B().__dict__)#B {}
應用場景
2、未實現和未實現的異常
3、運算符重載中的反向方法
class A: def __init__(self,x): self.x = x def __add__(self, other): print(self,'add') return self.x + other.x def __iadd__(self, other): print(self,'iadd') return A(self.x + other.x) def __radd__(self, other): print(self,'radd') return self.x + other.x a = A(4) b = A(5) print(a,b) print(a+b) print(b+a) b+=a a+=b #運行結果: <__main__.A object at 0x0000000002965080> <__main__.A object at 0x00000000029650B8> <__main__.A object at 0x0000000002965080> add 9 <__main__.A object at 0x00000000029650B8> add 9 <__main__.A object at 0x00000000029650B8> iadd <__main__.A object at 0x0000000002965080> iadd
class A: def __init__(self,x): self.x = x def __add__(self, other): print(self,'add') return self.x + other.x def __iadd__(self, other): print(self,'iadd') return A(self.x + other.x) def __radd__(self, other): print(self,'radd') return self.x + other.x a = A(4) a+1 #運行結果: <__main__.A object at 0x00000000029356D8> add Traceback (most recent call last): File "F:/code_python_urllib_demo/Python全棧開發--異常及模塊/test.py", line 18, in <module> a+1 File "F:/code_python_urllib_demo/Python全棧開發--異常及模塊/test.py", line 7, in __add__ return self.x + other.x AttributeError: 'int' object has no attribute 'x'
class A: def __init__(self,x): self.x = x def __add__(self, other): print(self,'add') return self.x + other.x def __iadd__(self, other): print(self,'iadd') return A(self.x + other.x) def __radd__(self, other): print(self,'radd') return self.x + other.x class B: def __init__(self,x): self.x = x a = A(4) b = B(10) print(a+b) print(b+a) #運行結果 <__main__.A object at 0x00000000029A5080> add 14 <__main__.A object at 0x00000000029A5080> radd 14
class A: def __init__(self,x): self.x = x def __add__(self, other): print(self,'add') try: return self.x + other.x except AttributeError: try: x = int(other) except: x = 0 return self.x + x def __iadd__(self, other): print(self,'iadd') return A(self.x + other.x) def __radd__(self, other): print(self,'radd') return self + other class B: def __init__(self,x): self.x = x a = A(4) b = B(10) print(a+b) print(b+a) print(a+2) print(2+a) print(a+'abc') print('abc'+a) #運行結果: <__main__.A object at 0x0000000002965048> add 14 <__main__.A object at 0x0000000002965048> radd <__main__.A object at 0x0000000002965048> add 14 <__main__.A object at 0x0000000002965048> add 6 <__main__.A object at 0x0000000002965048> radd <__main__.A object at 0x0000000002965048> add 6 <__main__.A object at 0x0000000002965048> add 4 <__main__.A object at 0x0000000002965048> radd <__main__.A object at 0x0000000002965048> add 4