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 herhangiabc
var mı?Sequence
vs etrafında bir taslak benzeri kaplar etrafında herhangi bir tasarım tartışması var mı?
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
@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