1. 程式人生 > >day 21 - 1 包,異常處理

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)