国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語(yǔ)言編程技術(shù)及教程分享平臺(tái)!
分類(lèi)導(dǎo)航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務(wù)器之家 - 腳本之家 - Python - 構(gòu)建Python包的五個(gè)簡(jiǎn)單準(zhǔn)則簡(jiǎn)介

構(gòu)建Python包的五個(gè)簡(jiǎn)單準(zhǔn)則簡(jiǎn)介

2020-07-15 10:20腳本之家 Python

這篇文章主要介紹了構(gòu)建Python包的五個(gè)簡(jiǎn)單準(zhǔn)則簡(jiǎn)介,在Github開(kāi)源合作日趨主流的今天,健壯的Python包的構(gòu)建成為開(kāi)發(fā)者必須要考慮到的問(wèn)題,本文提出了五項(xiàng)建議,需要的朋友可以參考下

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

對(duì)于一個(gè)簡(jiǎn)單的軟件包,你可能會(huì)忍不住把工具方法,工廠方法和異常處理都丟進(jìn)__init__.py,千萬(wàn)別這樣!

一個(gè)結(jié)構(gòu)良好的__init__.py文件,僅為一個(gè)非常重要的目的來(lái)服務(wù):從子模塊導(dǎo)入。你的__init__.py應(yīng)該看起來(lái)像這個(gè)樣子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# ORDER MATTERS HERE -- SOME MODULES ARE DEPENDANT ON OTHERS
# 導(dǎo)入順序要考慮——一些模塊會(huì)依賴(lài)另外的一些
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來(lái)限制導(dǎo)入順序

  •     把方法和類(lèi)置于軟件包的作用域中,這樣用戶(hù)就不需要深入軟件包的內(nèi)部結(jié)構(gòu),使你的軟包變得易用。
  •     作為調(diào)和導(dǎo)入順序的唯一地方。

使用得當(dāng)?shù)脑挘琠_init__.py 可以為你提供重新組織內(nèi)部軟件包結(jié)構(gòu)的靈活性,而不需要擔(dān)心由內(nèi)部導(dǎo)入子模塊或是每個(gè)模塊導(dǎo)入順序所帶來(lái)的副作用。因?yàn)槟闶且砸粋€(gè)特定的順序?qū)胱幽K,你的__init__.py 對(duì)于他程序員來(lái)講應(yīng)該簡(jiǎn)單易懂,并且能夠明顯的表示該軟件包所能提供的全部功能。

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

?
1
2
3
4
5
6
7
8
9
10
__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.使用一個(gè)模塊來(lái)定義所有的異常

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

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

你應(yīng)該為你的軟件包的異常定義一個(gè)基類(lèi):

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

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

?
1
2
3
4
5
6
try:
  
'''bunch of code from your package'''
except APackageException:
  
'''blanked condition to handle all errors from your package'''

對(duì)于一般的錯(cuò)誤狀態(tài),這里有一些重要的異常處理已經(jīng)被包括在標(biāo)準(zhǔn)庫(kù)中了(例如,TypeError, ValueError等)

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
# 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

在你的異常處理中保持更大的粒度,有利于讓程序員們?cè)谝粋€(gè)try/except中包含越來(lái)越大的,互相不干涉的代碼段。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 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'''

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

在子模塊中你時(shí)常見(jiàn)到的一個(gè)簡(jiǎn)單錯(cuò)誤,就是使用軟件包的名字來(lái)導(dǎo)入軟件包。

?
1
2
# within a sub-module
from a_package import APackageError

這樣做會(huì)導(dǎo)致兩個(gè)不好的結(jié)果:

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

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

?
1
2
3
4
5
6
7
# 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ī)模

你的模塊應(yīng)當(dāng)比較小。記住,那個(gè)使用你軟件包的程序員會(huì)在軟件包作用域進(jìn)行導(dǎo)入,同時(shí)你會(huì)使用你的 __init__.py 文件來(lái)作為一個(gè)組織工具,來(lái)暴露一個(gè)完整的接口。

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

?
1
2
3
4
5
6
7
class APackageClass(object):
  
'''One class'''
 
def apackage_builder(how_many):
  for i in range(how_many):
    yield APackageClass()

如果你的模塊暴露了一些方法,把一些相互依賴(lài)的方法分為一組放進(jìn)一個(gè)模塊,并且把不相互依賴(lài)的方法移動(dòng)到單獨(dú)的模塊中:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
####### 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,它暴露了一系列的方法來(lái)為同一個(gè)功能提供不同的接口(就像 simplejson 中的l oad/loads)。盡管這個(gè)例子足夠直觀,讓你的模塊保持較小規(guī)模需要一些判斷,但是一個(gè)好的原則是:

當(dāng)你有疑問(wèn)的時(shí)候,就去創(chuàng)建一個(gè)新的子模塊吧。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 波多野结衣一区二区三区 | 欧美日韩在线播放 | 色花av| 中文字幕在线观看视频一区 | 中文字幕日产乱码六区小草 | 高清av网站 | 在线成人av | 精品成人 | 亚洲欧美另类久久久精品2019 | 亚洲精品一区二区 | 黄网站涩免费蜜桃网站 | 亚洲精品久久久久久久久久久久久 | 中文成人在线 | 国产成人免费 | 国产精品久久久久久久久久久免费看 | 久久久www成人免费无遮挡大片 | 欧美色图亚洲 | 在线色网 | 欧美区在线 | 亚洲热综合 | 亚洲视频一区在线播放 | 亚洲精品成人av久久 | 日韩在线观看一区 | 亚洲va国产天堂va久久 en | 91社影院在线观看 | 国产日韩欧美视频 | 精品国产一区二区三区免费 | 久久99一区二区 | 久久精品国产99国产精品 | 一本色道久久综合狠狠躁篇的优点 | 性刺激久久久久久久久九色 | 成人免费网站在线 | 欧美在线观看视频一区二区 | 字幕网av| 亚洲免费视频一区二区 | 久久久婷婷一区二区三区不卡 | 久久久久久国产 | 成人av免费观看 | 欧美精品久久 | 日韩一级电影在线 | 成人欧美一区二区三区在线观看 |