国产99久久精品_欧美日本韩国一区二区_激情小说综合网_欧美一级二级视频_午夜av电影_日本久久精品视频

最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當前位置: 首頁 - 科技 - 知識百科 - 正文

構(gòu)建Python包的五個簡單準則簡介

來源:懂視網(wǎng) 責編:小采 時間:2020-11-27 14:34:02
文檔

構(gòu)建Python包的五個簡單準則簡介

構(gòu)建Python包的五個簡單準則簡介:創(chuàng)建一個軟件包(package)似乎已經(jīng)足夠簡單了,也就是在文件目錄下搜集一些模塊,再加上一個__init__.py文件,對吧?我們很容易看出來,隨著時間的推移,通過對軟件包的越來越多的修改,一個設(shè)計很差的軟件包可能會出現(xiàn)循環(huán)依賴問題,或是可能變得不可移植和
推薦度:
導讀構(gòu)建Python包的五個簡單準則簡介:創(chuàng)建一個軟件包(package)似乎已經(jīng)足夠簡單了,也就是在文件目錄下搜集一些模塊,再加上一個__init__.py文件,對吧?我們很容易看出來,隨著時間的推移,通過對軟件包的越來越多的修改,一個設(shè)計很差的軟件包可能會出現(xiàn)循環(huán)依賴問題,或是可能變得不可移植和

創(chuàng)建一個軟件包(package)似乎已經(jīng)足夠簡單了,也就是在文件目錄下搜集一些模塊,再加上一個__init__.py文件,對吧?我們很容易看出來,隨著時間的推移,通過對軟件包的越來越多的修改,一個設(shè)計很差的軟件包可能會出現(xiàn)循環(huán)依賴問題,或是可能變得不可移植和不可靠。
1. __init__.py 僅為導入服務

對于一個簡單的軟件包,你可能會忍不住把工具方法,工廠方法和異常處理都丟進__init__.py,千萬別這樣!

一個結(jié)構(gòu)良好的__init__.py文件,僅為一個非常重要的目的來服務:從子模塊導入。你的__init__.py應該看起來像這個樣子:

# ORDER MATTERS HERE -- SOME MODULES ARE DEPENDANT ON OTHERS
# 導入順序要考慮——一些模塊會依賴另外的一些
from exceptions import FSQError, FSQEnvError, FSQEncodeError,
 FSQTimeFmtError, FSQMalformedEntryError,
 FSQCoerceError, FSQEnqueueError, FSQConfigError,
 FSQPathError, FSQInstallError, FSQCannotLockError,
 FSQWorkItemError, FSQTTLExpiredError,
 FSQMaxTriesError, FSQScanError, FSQDownError,
 FSQDoneError, FSQFailError, FSQTriggerPullError,
 FSQHostsError, FSQReenqueueError, FSQPushError 
 
# constants relies on: exceptions, internal
import constants
 
# const relies on: constants, exceptions, internal
from const import const, set_const 
# has tests
 
# path relies on: exceptions, constants, internal
import path 
# has tests
 
# lists relies on: path
from lists import hosts, queues
 
#...

2.使用__init__.py來限制導入順序

  • 把方法和類置于軟件包的作用域中,這樣用戶就不需要深入軟件包的內(nèi)部結(jié)構(gòu),使你的軟包變得易用。
  • 作為調(diào)和導入順序的唯一地方。
  • 使用得當?shù)脑挘琠_init__.py 可以為你提供重新組織內(nèi)部軟件包結(jié)構(gòu)的靈活性,而不需要擔心由內(nèi)部導入子模塊或是每個模塊導入順序所帶來的副作用。因為你是以一個特定的順序?qū)胱幽K,你的__init__.py 對于他程序員來講應該簡單易懂,并且能夠明顯的表示該軟件包所能提供的全部功能。

    文檔字符串,以及在軟件包層面對__all__屬性的賦值應當是__init__.py中唯一的與導入模塊不相關(guān)的代碼:

    __all__ = [ 'FSQError', 'FSQEnvError', 'FSQEncodeError', 'FSQTimeFmtError',
     'FSQMalformedEntryError', 'FSQCoerceError', 'FSQEnqueueError',
     'FSQConfigError', 'FSQCannotLock', 'FSQWorkItemError',
     'FSQTTLExpiredError', 'FSQMaxTriesError', 'FSQScanError',
     'FSQDownError', 'FSQDoneError', 'FSQFailError', 'FSQInstallError',
     'FSQTriggerPullError', 'FSQCannotLockError', 'FSQPathError',
     'path', 'constants', 'const', 'set_const', 'down', 'up',
     
    # ...
     ]
    

    3.使用一個模塊來定義所有的異常

    你也許已經(jīng)注意到了,__init__.py中的第一個導入語句從exceptions.py子模塊中導入了全部的異常。從這里出發(fā),你將看到,在大多數(shù)的軟件包中,異常被定義在引起它們的代碼附近。盡管這樣可以為一個模塊提供高度的完整性,一個足夠復雜的軟件包會通過如下兩種方式,使得這一模式出現(xiàn)問題。

    通常一個模塊/程序需要從一個子模塊導入一個函數(shù), 利用它導入代碼并拋出異常。為了捕獲異常并保持一定的粒度,你需要導入你需要的模塊,以及定義了異常的模塊(或者更糟,你要導入一系列的異常)。這一系列衍生出來的導入需求,是在你的軟件包中編織一張錯綜復雜的導入之網(wǎng)的始作俑者。你使用這種方式的次數(shù)越多,你的軟件包內(nèi)部就變的越相互依賴,也更加容易出錯。
    隨著異常數(shù)量的不斷增長,找到一個軟件包可能引發(fā)的全部異常變的越來越難。把所有的異常定義在一個單獨的模塊中,提供了一個方便的地方,在這里,程序員可以審查并確定你的軟件包所能引發(fā)全部潛在錯誤狀態(tài)。

    你應該為你的軟件包的異常定義一個基類:

    class APackageException(Exception):
     
    '''root for APackage Exceptions, only used to except any APackage error, never raised'''
     pass
    

    然后確保你的軟件包在任何錯誤狀態(tài)下,只會引發(fā)這個基類異常的子類異常,這樣如果你需要的話,你就可以阻止全部的異常:

    try:
     
    '''bunch of code from your package'''
    except APackageException:
     
    '''blanked condition to handle all errors from your package'''
    

    對于一般的錯誤狀態(tài),這里有一些重要的異常處理已經(jīng)被包括在標準庫中了(例如,TypeError, ValueError等)

    靈活地定義異常處理并保持足夠的粒度:

    # from fsq
    class FSQEnvError(FSQError):
     
    '''An error if something cannot be loaded from env, or env has an invalid
     
    value'''
     pass
     
    class FSQEncodeError(FSQError):
     
    '''An error occured while encoding or decoding an argument'''
     pass
    # ... and 20 or so more
    

    在你的異常處理中保持更大的粒度,有利于讓程序員們在一個try/except中包含越來越大的,互相不干涉的代碼段。

    # this
    try:
     item = fsq.senqueue('queue', 'str', 'arg', 'arg')
     scanner = fsq.scan('queue')
    except FSQScanError:
     
    '''do something'''
    except FSQEnqueueError:
     
    '''do something else'''
     
    # not this
    try:
     item = fsq.senqueue('queue', 'str', 'arg', 'arg')
    except FSQEnqueueError:
     
    '''do something else'''
    try:
     scanner = fsq.scan('queue')
    except FSQScanError:
     
    '''do something'''
     
    # and definitely not
    try:
     item = fsq.senqueue('queue', 'str', 'arg', 'arg')
     try:
     scanner = fsq.scan('queue')
     except FSQScanError:
     
    '''do something'''
    except FSQEnqueueError:
     
    '''do something else'''
    

    在異常定義時保持高度的粒度,會減少錯綜復雜的錯誤處理,并且允許你把正常執(zhí)行指令和錯誤處理指令分別開來,使你的代碼更加易懂和更易維護。
    4. 在軟件包內(nèi)部只進行相對導入

    在子模塊中你時常見到的一個簡單錯誤,就是使用軟件包的名字來導入軟件包。

    # within a sub-module
    from a_package import APackageError
    

    這樣做會導致兩個不好的結(jié)果:

    1. 子模塊只有當軟件包被安裝在 PYTHONPATH 內(nèi)才能正確運行。
    2. 子模塊只有當這個軟件包的名字是 a_package 時才能正確運行。

    盡管第一條看上去并不是什么大問題,但是考慮一下,如果你在 PYTHONPATH 下的兩個目錄中,有兩個同名的軟件包。你的子模塊可能最終導入了另一個軟件包,你將無意間使得某個或某些對此毫無戒備的程序員(或是你自己)debug 到深夜。

    # within a sub-module 
    from . import FSQEnqueueError, FSQCoerceError, FSQError, FSQReenqueueError,
     constants as _c, path as fsq_path, construct,
     hosts as fsq_hosts, FSQWorkItem
    from .internal import rationalize_file, wrap_io_os_err, fmt_time,
     coerce_unicode, uid_gid
    # you can also use ../... etc. in sub-packages.
    

    5. 讓模塊保持較小的規(guī)模

    你的模塊應當比較小。記住,那個使用你軟件包的程序員會在軟件包作用域進行導入,同時你會使用你的 __init__.py 文件來作為一個組織工具,來暴露一個完整的接口。

    好的做法是一個模塊只定義一個類,伴隨一些幫助方法和工廠方法來協(xié)助建立這個模塊。

    class APackageClass(object):
     
    '''One class'''
     
    def apackage_builder(how_many):
     for i in range(how_many):
     yield APackageClass()
    

    如果你的模塊暴露了一些方法,把一些相互依賴的方法分為一組放進一個模塊,并且把不相互依賴的方法移動到單獨的模塊中:

    ####### EXPOSED METHODS #######
    def enqueue(trg_queue, item_f, *args, **kwargs):
     
    '''Enqueue the contents of a file, or file-like object, file-descriptor or
     
    the contents of a file at an address (e.g. '/my/file') queue with
     
    arbitrary arguments, enqueue is to venqueue what printf is to vprintf
     
    '''
     return venqueue(trg_queue, item_f, args, **kwargs)
     
    def senqueue(trg_queue, item_s, *args, **kwargs):
     
    '''Enqueue a string, or string-like object to queue with arbitrary
     
    arguments, senqueue is to enqueue what sprintf is to printf, senqueue
     
    is to vsenqueue what sprintf is to vsprintf.
     
    '''
     return vsenqueue(trg_queue, item_s, args, **kwargs)
     
    def venqueue(trg_queue, item_f, args, user=None, group=None, mode=None):
     
    '''Enqueue the contents of a file, or file-like object, file-descriptor or
     
    the contents of a file at an address (e.g. '/my/file') queue with
     
    an argument list, venqueue is to enqueue what vprintf is to printf
     
    if entropy is passed in, failure on duplicates is raised to the caller,
     
    if entropy is not passed in, venqueue will increment entropy until it
     
    can create the queue item.
     
    '''
     
    # setup defaults
     trg_fd = name = None
     
    # ...
    

    上面的例子是 fsq/enqueue.py,它暴露了一系列的方法來為同一個功能提供不同的接口(就像 simplejson 中的l oad/loads)。盡管這個例子足夠直觀,讓你的模塊保持較小規(guī)模需要一些判斷,但是一個好的原則是:

    當你有疑問的時候,就去創(chuàng)建一個新的子模塊吧。

    聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    構(gòu)建Python包的五個簡單準則簡介

    構(gòu)建Python包的五個簡單準則簡介:創(chuàng)建一個軟件包(package)似乎已經(jīng)足夠簡單了,也就是在文件目錄下搜集一些模塊,再加上一個__init__.py文件,對吧?我們很容易看出來,隨著時間的推移,通過對軟件包的越來越多的修改,一個設(shè)計很差的軟件包可能會出現(xiàn)循環(huán)依賴問題,或是可能變得不可移植和
    推薦度:
    標簽: 介紹 包的 python
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 日韩阿v| 日产精品久久久一区二区 | 久草天堂 | 国产欧美综合精品一区二区 | 在线日韩欧美一区二区三区 | 久久综合伊人77777麻豆 | 亚洲欧美精品在线 | 国产在线播放免费 | 国产 欧美 日韩 在线 | 日韩精品第二页 | 精品伊人久久久久7777人 | 欧美日韩中文 | 国产精品一区二区久久不卡 | 一区二区三区视频 | 一级毛片免费毛片毛片 | 欧美日韩视频一区三区二区 | 国产一区二区三区欧美精品 | 欧日韩一区二区三区 | 成a人片亚洲日本久久 | 欧美视频亚洲 | 最新国产精品亚洲 | 亚洲视频免费观看 | 日韩在线观看视频网站 | 最新国产精品视频免费看 | 国产精品1区2区 | 欧美精品一区二区三区免费观看 | 日本不卡视频一区二区 | 久久国产一区二区 | 久久久影院亚洲精品 | 欧美色乱| 在线亚洲激情 | 国产黄色片一级 | 久久久精品久久久久久久久久久 | 综合精品欧美日韩国产在线 | 欧美精品v国产精品v日韩精品 | 欧美日韩亚洲视频 | 亚洲欧美精品成人久久91 | 日韩免费观看 | 久久久久久久国产精品毛片 | 欧美成人精品在线 | 伊人精品在线视频 |