2017-04-19 45 views
6

kullanılarak string benzeri olmayan diziler nasıl test edilir? Bazı zamanlar için Python, özellikle kapsayıcı türleri için Abstract Base Classes (orientally PEP 3119 olarak önerilmiştir) için özel olarak genelleştiren kod yazmayı kolaylaştırır. türleri. Örneğin, birkaç kez beni takıldı oluyor 'Sorunlar' arasındaPython 3'ün standart kitaplığı

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 

Bir, bytes o str ve bytearray daha açıkçası liste benzeri nesnelere ek olarak, Sequence s kabul edilir:

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] 

Bu kesinlikle mantıklıdır: genellikle bu üç tür, karakterlerin (veya baytların) listeleri veya tuples'i gibi davranır. Ancak, sormak için oldukça yaygın bir kullanım durumu gibi görünüyor, bu nesne x hem liste gibi ve dize gibi değil mi? düzeltme basittir:

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] 

Ama ben standart kütüphanesinde şey eksik acaba ortak yeterince desen olurdu gibi bu görünüyor.

  • islistlike = lambda x: isinstance(x, abc) yukarıdaki Son örnekte görüldüğü gibi davranacaktır şekilde Python'ın standart kitaplığındaki herhangi abc var mı?
  • Sequence vs etrafında bir taslak benzeri kaplar etrafında herhangi bir tasarım tartışması var mı?
+0

1. Bildiğim kadarıyla değil. 2. Dikkat edeceğiniz gibi, * "string-like kapsayıcılar" * * * dizileri, tek-karakterli dizgiler/baytlar dizisidir ('ByteString', 'Dizi', hatta '), yani" vs "* gerçekten yapmaz duygusu. Birçok durumda bir dizge, bir dizi alan bir işlev veya yönteme tam olarak geçerli bir argüman olarak kabul edilir, bu durumda durum böyle olmadığında açık olmak zorundasınız. – jonrsharpe

+0

@jonrsharpe Yorumlarınız için teşekkür ederiz! Durumuna bağlı olarak, "* vs *" nin uygun olabileceğini iddia ediyorum. Genellikle, tek atomlu veri noktaları olarak dizeleri (bayt, vs) düşünüyorum ve bilmek istiyorum, ben dize gibi öğeleri liste benzeri bir konteyner ile uğraşıyor muyum yoksa tek bir string-like ile uğraşıyor muyum? öğe. Bunun ortaya çıktığı yerlerden biri, iç içe geçmiş bir sözlüğü düzeltmek için, örneğin öğenin türüne göndermek istediğiniz özyineleme işlevinin içinde bir özyineleme işlevi kullanmaktır. – DGrady

cevap

1

Resim kolayca diğer sekans tipleri vs benzeri str ile bytes dizileri ayırt standart kitaplığı hiçbir şey (I standart kütüphane belgelerine veya PEP 3119. bu ile ilgili bir şey bulduk değil). Bu sizin kod tabanınızda yaygınsa, o zaman kendi hesabınızı kullanmak isteyebilirsiniz.