2015-10-28 19 views
10

Python'da yeni kullanıcılar için bir dizi test vakası yazıyorum. Testlerimde fark ettiğim problemlerden biri yanlış pozitiflerin elde edilmesinin mümkün olmasıdır. Şanslı olmuş olabilirler ve her öğeyi doğru sırayla verdiler, ancak gerçekten sipariş edilen bir yapı kullanmalılar.Python'da bir yapının siparişi olup olmadığını nasıl anlarım?

Şimdiye kadar bu ile gelebilir en iyi çözümdür.

self.assertTrue(isinstance(result, Sequence) or 
       isinstance(result, GeneratorType) or 
       callable(getattr(result, '__reversed__', False))) 

Ancak, ben GeneratorType gerçekten sıralanır güvenemeyen ya bu test kapsamlı olduğunu. Bunu test etmenin daha iyi bir yolu olmalı diye düşünüyorum. Bir yapının siparişi olduğunu nasıl test edebilirim?

Sen tamamen size "emri" sahip olma özelliği ile ne demek tarif değil
+1

Neyin peşinde olduğunuzu anlamak oldukça zor. Örnekler verin lütfen. Yapısal olarak 'veri tipi' mi demek istiyorsunuz? – Pynchia

+0

Bir işlevi çağırıyorum ve bir çeşit veri yapısı döndürüyor. Bana bir liste verebilirler, bana bir set verebilirler veya kendi yinelenebilir sınıflarını uygulayabilirlerdi. Bu yapının düzeni olduğunu ve yinelemeye karar verdiğimden bağımsız olarak aynı şekilde döneceğinden emin olmak istiyorum. –

+0

Örnek olarak, bir set sipariş edilmez. Bir liste sipariş edilir. Sipariş verilmediğinden, bir set test durumlarımdan doğal olarak başarısız olmalıdır. Test davalarımın bir listesi geçmeli. –

cevap

3

Bence çok ilginç soruluk olduğunu: yapısına bloğu dışında deneyin-bir ayar "af dile" yöntemi de vardır. toplama sipariş olup olmadığını kontrol etmek için saf Python (utility kodu olmadan) bir yolu yoktur.

Eğer collections.Iterable türünü kullanabilirsiniz

Sequence veya GeneratorType kontrol etmek) = en sırayla gidelim.

>>> 
>>> import collections 
>>> 
>>> result = [1,2,3,4,-1] 
>>> isinstance(result, collections.Iterable) 
True 
>>> 
>>> def generator_func(arg=10): 
...  for i in xrange(arg): 
...   yield i 
... 
>>> 
>>> generator_func() 
<generator object generator_func at 0x7f667c50f190> 
>>> 
>>> result = generator_func() 
>>> isinstance(result, collections.Iterable) 
True 

Ama:

>>> 
>>> result = {1,2,3,4,-1} 
>>> isinstance(result, collections.Iterable) 
True 
>>> 

Bu sizin için kötü bir durumdur. Çünkü: Bu durum için Elbette

>>> x = {1,2,3,-1} 
>>> x 
set([1, 2, 3, -1]) 
>>> [_ for _ in x] 
[1, 2, 3, -1] 
>>> x = {1,2,3,0} 
>>> x 
set([0, 1, 2, 3]) 
>>> [_ for _ in x] 
[0, 1, 2, 3] 
>>> import collections 
>>> isinstance(x, collections.Iterable) 
True 
>>> 

Bir collections.Sequence sadece kullanmalıdır.

>>> result = {1,2,3,4,-1} 
>>> isinstance(result, collections.Sequence) 
False 
>>> isinstance({1:2, 3:3}, collections.Sequence) 
False 
>>> 

Ama:

>>> result = generator_func() 
>>> isinstance(result, collections.Sequence) 
False 
>>> 

Böylece, ben bir fikir Sequence or GeneratorType güzel kontrol etmek olduğunu düşünüyorum. Yani

:

>>> result = generator_func() 
>>> isinstance(result, (collections.Sequence, collections.Iterator)) 
True 
>>> result = [1,2,3,4,5] 
>>> isinstance(result, (collections.Sequence, collections.Iterator)) 
True 
>>> result = (1,2,3,4,5) 
>>> isinstance(result, (collections.Sequence, collections.Iterator)) 
True 
>>> result = {1,2,3,4,5} 
>>> isinstance(result, (collections.Sequence, collections.Iterator)) 
False 
>>> result = {1:1,2:2,3:3,4:4,5:5} 
>>> isinstance(result, (collections.Sequence, collections.Iterator)) 
False 
>>> 

Аbout sırası bu bağlantıyı kontrol edin . Eğer öğelerin sipariş hakkında emin değilseniz

, ben bunları açıkça kontrol etmeliyiz.

«Açık örtülü daha iyidir.

>>> 
>>> def order_check(result, order_rule = cmp_rule): 
...  for item, next_item in zip(result, result[1:]): 
...   if not order_rule(item, next_item): 
...    return False 
...  return True 
... 
>>> def cmp_rule(item, next_item): 
...  if item < next_item: 
...   return True 
...  return False 
... 
>>> 
>>> result = [1,2,3,4,5] 
>>> order_check(result) 
True 
>>> result = [1,2,3,4,5,-1] 
>>> order_check(result) 
False 
>>> 

»Fakat dürüstçe, jeneratörler Eğer içinde üretmek olarak sipariş aynı olacaktır garanti.

-1

; senin "callable" senin için iyi bir fikir. Sana (çift alt çizgi) yöntemleri bunlardan biri istediğiniz tanımını eşleşen olup olmadığını görmek için "Dunder" okumanızı öneririz. Bize verdiğiniz şeyden, __getitem__'un istediğiniz şey olduğundan şüpheleniyorum.

try: 
    dummy = (_ for _ in result) 
    has_order = True 
except: 
    has_order = False 
return has_order 
+1

İlk paragraftan itibaren OP sadece "yinelenen" anlamına gelmez, tüm örnek kodunuz kontrol edilir. –

+0

Katılıyorum: bu cevap oldukça yetersiz. @Kyle Strand bunu değerli bir nokta yapar, bu yüzden cevabı burada bırakıp 2 puanlık kesinti yapacağım. :-) – Prune

İlgili konular