Python進階11---異常及模塊化

異常處理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

相關文章
相關標籤/搜索