day 21 - 1 包,異常處理
建立目錄程式碼
1. 無論是 import 形式還是 from...import 形式,凡是在匯入語句中(而不是在使用時)遇到帶點的,都要第一時間提高警覺:這是關於包才有的匯入語法
2. 包是目錄級的(資料夾級),資料夾是用來組成py檔案(包的本質就是一個包含__init__.py檔案的目錄)
3. import 匯入檔案時,產生名稱空間中的名字來源於檔案,import 包,產生的名稱空間的名字同樣來源於檔案,即包下的 __init__.py ,匯入包本質就是在匯入該檔案
強調:
1. 在python3中,即使包下沒有 __init__.py 檔案,import 包仍然不會報錯,而在 python2 中,包下一定要有該檔案,否則 import 包報錯
2. 建立包的目的不是為了執行,而是被匯入使用,記住,包只是模組的一種形式而已,包即模組
注意:
1. 關於包相關的匯入語句也分為 import 和 from ... import ... 兩種,但是無論哪種,無論在什麼位置,在匯入時都必須遵循一個原則:凡是在匯入時帶點的,點的左邊都必須是一個包,否則非法。可以帶有一連串的點,如 item.subitem.subsubitem,但都必須遵循這個原則
2. 對於匯入後,在使用時就沒有這種限制了,點的左邊可以是包,模組,函式,類(它們都可以用點的方式呼叫自己的屬性)
如下建立的包
import os os.makedirs('E:/py/bao/api') os.makedirs('E:/py/bao/cmd') os.makedirs('E:/py/bao/db') l = [] l.append(open('E:/py/bao/__init__.py','w')) l.append(open('E:/py/bao/api/__init__.py','w')) l.append(open('E:/py/bao/api/policy.py','w')) l.append(open('E:/py/bao/api/versions.py','w')) l.append(open('E:/py/bao/cmd/__init__.py','w')) l.append(open('E:/py/bao/cmd/manage.py','w')) l.append(open('E:/py/bao/db/models.py','w')) l.append(open('E:/py/bao/db/__init__.py','w')) map(lambda f:f.close() ,l)
如下的一個目錄結構
glance/ ├── __init__.py from .api import * from .cmd import * from.db import * ├── api │ ├── __init__.py __all__ = ['policy','versions'] │ ├── policy.py │ └── versions.py ├── cmd __all__ = ['manage'] │ ├── __init__.py │ └── manage.py └── db __all__ = ['models'] ├── __init__.py └── models.py import glance policy.get()
接下來我們來嘗試呼叫模組
import bao.api.policy as policy policy.get() from bao.api import policy #import 後面不能帶“.”什麼 policy.get() import sys print(sys.path) #檢視配置路徑 ##我們嘗試 import 包,然後使用其下面的方法 #原因是:當匯入一個包時,一定執行包下面的 __init__.py 檔案,此時我們改檔案為空 import bao bao.api.policy.get() #報錯 AttributeError: module 'bao' has no attribute 'api' #然後我們要做的就是在沒一級包中的 __init__.py 中匯入要用到的下一級的包,需要注意的是 sys.path 的路徑
我們在 __init__.py 中匯入包時
from bao.api import policy #絕對路徑
from . import policy #相對路徑
絕對路徑:
使用絕對路徑 不管在包內部還是外部 匯入了就能用
不能挪動,但是直觀
相對路徑:(當使用一個成熟的包時使用)
可以隨意移動包 只要能找到包的位置,就可以使用包裡的模組
包裡的模組如果想使用其它模組的內容只能使用相對路徑,使用了相對路徑就不能在包內直接執行了
## __all__ 與 from ... import * 配合的匯入方式
#可以忽略中間一層的檔名
異常處理
先來看一串程式碼,後面在慢慢解釋
try: print('1111') # 1/0 print('2222') # name # 2+'3' # [][3] # {}['k'] ret = int(input('number >>>')) print(ret*'*') except ValueError: print('輸入的資料型別有誤') except Exception: print('你錯了,老鐵') else: print('沒有異常的時候執行else中的程式碼') print('===========') def func(): try: f = open('file','w') return True except: return False finally: print('執行 finally 了') f.close() print(func())
程式一旦發生錯誤,就從錯誤的位置停下來了,不在繼續執行後面的內容
使用 try 和 except 就能處理異常
try 是我們需要處理的程式碼
except 後面跟一個錯誤型別 當代碼發生錯誤且錯誤型別符合的時候 就會執行 except 中的程式碼
except 支援多分支
有沒有一個能處理所有錯誤的型別:Exception
有了萬能的處理機制仍然需要把能預測到的問題單獨處理
單獨處理的所有內容都應該寫在萬能異常之前
else:沒有異常的時候執行 else 中的程式碼
finally:不管程式碼是否異常,都會執行
finally 和 return 相遇的時候 依然會執行
函式裡做異常處理用,不管是否異常去做一些收尾工作
在 Exception 後加上 error
try: print('1111') # 1/0 print('2222') # name # 2+'3' # [][3] # {}['k'] ret = int(input('number >>>')) print(ret*'*') except Exception as error: #在使用萬能異常處理時,加上 error 可以顯示報錯資訊 print('你錯了,老鐵',error)