2017-04-19 54 views
6

一段時間以來,Python已經有Abstract Base Classes(建議orignally在PEP 3119中),尤其是對於容器類型,可以更輕鬆地編寫在整個自定義類型。例如,如何使用Python 3的標準庫測試不像字符串的序列

from collections.abc import Sequence, Set 

if isinstance(x, Sequence): 
    # Handle lists, tuples, or custom objects that behave like lists 
elif isinstance(x, Set): 
    # Handle anything that behaves like a set 

一個多數民衆贊成我絆倒了幾次「陷阱」的是strbytesbytearray都被認爲是Sequence S,除了更爲明顯名單狀物體:

from collections.abc import ByteString, Sequence 

s = 'hello' 
b = b'hello' 
ba = bytearray(b'hello') 
lst = [0, 1, 2] 
t = (0, 1, 2) 

islistlike = lambda x: isinstance(x, Sequence) 

list(map(islistlike, [s, b, ba, lst, t])) # -> [True, True, True, True, True] 

這當然有意義:通常這三種類型的行爲就像列表或字符元組(或字節)。但是,這似乎是一個相當常見的用例,請問這個對象是x既是列表式的又不是字符串式的?解決方法是直截了當:

islistlike = lambda x: isinstance(x, Sequence) and not isinstance(x, (str, ByteString)) 

list(map(islistlike, [s, b, ba, lst, t])) # -> [False, False, False, True, True] 

但這似乎這將是一個足夠常見的模式,我不知道如果我錯過在標準庫的東西。

  • 是否有Python的標準庫中的任何abc這樣islistlike = lambda x: isinstance(x, abc)會像上面的最後一個例子?
  • 圍繞Sequence vs字符串像容器有什麼設計討論嗎? (我還沒有找到標準庫的文檔或PEP 3119在與此相關的任何東西)
+0

1.據我所知。 2.正如你注意到的那樣,*「string-like containers」* *是單個字符串/字節的序列('ByteString'繼承'Sequence',even),所以*「vs」*並不真正使感。在許多情況下,一個字符串被認爲是一個函數或方法的一個完全有效的參數,所以你必須在不是這種情況時纔是明確的。 – jonrsharpe

+0

@jonrsharpe感謝您的評論!我認爲「* vs *」可能是合適的,取決於具體情況。通常,我將字符串(字節等)看作單個原子數據點,我想知道,我是在處理類似字符串項目的列表狀容器,還是我正在處理單個字符串類型項目。這裏出現的一個地方是使用遞歸函數來扁平化一個嵌套的字典,例如 - 在您想要在項目類型上分派的遞歸函數內。 – DGrady

回答

1

沒有,沒有什麼標準庫,便於區分序列VS其他序列類型strbytes之間樣。如果這在你的代碼庫中很常見,那麼你可能想要推出自己的代碼庫。

相關問題