Python全棧學習筆記day 21:包、軟體開發規範、異常處理
一、包
1. 無論是import形式還是from...import形式,凡是在匯入語句中(而不是在使用時)遇到帶點的,都要第一時間提高警覺:這是關於包才有的匯入語法
2. 包是目錄級的(資料夾級),資料夾是用來組成py檔案(包的本質就是一個包含__init__.py檔案的目錄)
3. import匯入檔案時,產生名稱空間中的名字來源於檔案,import 包,產生的名稱空間的名字同樣來源於檔案,即包下的__init__.py,匯入包本質就是在匯入該檔案
強調:
1. 在python3中,即使包下沒有__init__.py檔案,import 包仍然不會報錯,而在python2中,包下一定要有該檔案,否則import 包報錯
2. 建立包的目的不是為了執行,而是被匯入使用,記住,包只是模組的一種形式而已,包即模組
1.1 注意事項:
1.關於包相關的匯入語句也分為import和from ... import ...兩種,但是無論哪種,無論在什麼位置,在匯入時都必須遵循一個原則:凡是在匯入時帶點的,點的左邊都必須是一個包,否則非法。可以帶有一連串的點,如item.subitem.subsubitem,但都必須遵循這個原則。
2.對於匯入後,在使用時就沒有這種限制了,點的左邊可以是包,模組,函式,類(它們都可以用點的方式呼叫自己的屬性)。
3.對比import item 和from item import name的應用場景:
如果我們想直接使用name那必須使用後者。
在啟動檔案中輸入以下程式碼:
import os os.makedirs('glance/api') os.makedirs('glance/cmd') os.makedirs('glance/db') l = [] l.append(open('glance/__init__.py','w')) l.append(open('glance/api/__init__.py','w')) l.append(open('glance/api/policy.py','w')) l.append(open('glance/api/versions.py','w')) l.append(open('glance/cmd/__init__.py','w')) l.append(open('glance/cmd/manage.py','w')) l.append(open('glance/db/__init__.py','w')) l.append(open('glance/db/models.py','w')) map(lambda f:f.close() ,l) 建立目錄程式碼
目錄結構:
在檔案中輸入以下內容:
#檔案內容
#policy.py
def get():
print('from policy.py')
#versions.py
def create_resource(conf):
print('from version.py: ',conf)
#manage.py
def main():
print('from manage.py')
#models.py
def register_models(engine):
print('from models.py: ',engine)
1.2 import
在啟動檔案(與包glance同級別的檔案中)中輸入以下程式碼就可以使用包:
import glance.db.models
glance.db.models.register_models('mysql')
1.3 from ... import ...
需要注意的是from後import匯入的模組,必須是明確的一個不能帶點,否則會有語法錯誤,如:from a import b.c是錯誤語法
from glance.db import models
models.register_models('mysql')
from glance.db.models import register_models
register_models('mysql')
1.4 __init__.py檔案
不管是哪種方式,只要是第一次匯入包或者是包的任何其他部分,都會依次執行包下的__init__.py檔案(我們可以在每個包的檔案內都列印一行內容來驗證一下),這個檔案可以為空,但是也可以存放一些初始化包的程式碼。
1.5 絕對路徑匯入:
在包glance中的__init__.py檔案寫入:
from glance import api
from glance import cmd
from glance import db
在api中的__init__.py檔案寫入:
from glance.api import policy
from glance.api import versions
在cmd中的__init__.py檔案寫入:
from glance.cmd import manage
在db中的__init__.py檔案寫入:
from glance.db import models
那現在在啟動檔案可以這樣啟動:
import glance
glance.db.models.register_models('mysql')
使用絕對路徑 不管在包內部還是外部 匯入了就能用 不能挪動,但是直觀
1.6 相對路徑
可以隨意移動包 只要能找到包的位置,就可以使用包裡的模組
包裡的模組如果想使用其它模組的內容只能使用相對路徑,使用了相對路徑就不能在包內直接執行了
在包裡面不能使用相對路徑
.. 上一層目錄
. 本層目錄
特別需要注意的是:
可以用import匯入內建或者第三方模組(已經在sys.path中),但是要絕對避免使用import來匯入自定義包的子模組(沒有在sys.path中),應該使用from... import ...的絕對或者相對匯入,且包的相對匯入只能用from的形式。
二、軟體開發規範
三、異常處理
part1:基本語法
try:
被檢測的程式碼塊
except 異常型別:
try中一旦檢測到異常,就執行這個位置的邏輯
栗子:
try:
f = open('a.txt')
g = (line.strip() for line in f)
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
except StopIteration:
f.close()
'''
next(g)會觸發迭代f,依次next(g)就可以讀取檔案的一行行內容,無論檔案a.txt有多大,同一時刻記憶體中只有一行內容。
提示:g是基於檔案控制代碼f而存在的,因而只能在next(g)丟擲異常StopIteration後才可以執行f.close()
'''
part2:異常類只能用來處理指定的異常情況,如果非指定異常則無法處理。
未捕獲到異常,程式直接報錯
s1 = 'hello'
try:
int(s1)
except IndexError as e:
print e
part3:多分支
s1 = 'hello'
try:
int(s1)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except ValueError as e:
print(e)
part4:萬能異常 在python的異常中,有一個萬能異常:Exception,他可以捕獲任意異常,即:
s1 = 'hello'
try:
int(s1)
except Exception as e:
print(e)
part5:異常的其他機構
s1 = 'hello'
try:
int(s1)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except ValueError as e:
print(e)
else:
print('try內程式碼塊沒有異常則執行我')
finally:
print('無論異常與否,都會執行該模組,通常是進行清理工作')
part6:主動觸發異常
try:
raise TypeError('型別錯誤')
except Exception as e:
print(e)
part7:自定義異常
class EvaException(BaseException):
def __init__(self,msg):
self.msg=msg
def __str__(self):
return self.msg
try:
raise EvaException('型別錯誤')
except EvaException as e:
print(e)
part8:斷言
assert 條件
assert 1 == 1
assert 1 == 2