1. 程式人生 > >Python全棧學習筆記day 21:包、軟體開發規範、異常處理

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