Seite 1 von 1
unittest - Prüfe auf Typ
Verfasst: Sonntag 12. November 2006, 09:34
von TheGrudge
Hallo,
ich habe mir überlegt wie ich eine Funktion daraufhin testen kann, ob sie einen Generator zurückliefert.
Nun kam ich auf folgenden Code und wollte einfach nur mal fragen, ob das die beste Methode ist so etwas zu testen oder ob es irgendeine andere Möglichkeit gibt.
Code: Alles auswählen
def test_return_generator(self):
"""func1 should return a generator object"""
t = type(func1("test"))
self.assertEqual(t.__name__, "generator")
Verfasst: Sonntag 12. November 2006, 09:35
von TheGrudge
hmm also ich weiss nicht wie es bei euch aussieht, aber ich sehe keine Unterstriche... sollte also im Code heissen:
self.assertEqual(t.__name__, "generator")
Re: unittest - Prüfe auf Typ
Verfasst: Sonntag 12. November 2006, 11:34
von gerold
TheGrudge hat geschrieben:ich habe mir überlegt wie ich eine Funktion daraufhin testen kann, ob sie einen Generator zurückliefert.
Hallo TheGrudge!
Ich würde einfach nur prüfen, ob das Objekt das Attribut ``next`` besitzt:
Code: Alles auswählen
>>> def x():
... for i in range(2):
... yield i
...
>>> xx = x()
>>> print hasattr(xx, "next")
True
>>>
Code: Alles auswählen
def is_generator(generator_object):
return hasattr(generator_object, "next")
x = ( item for item in range(2) )
print is_generator(x)
mfg
Gerold
Verfasst: Sonntag 12. November 2006, 12:44
von TheGrudge
aber dann besteht doch auch ein Iterator den Test, oder etwa nicht? Es sollen wirklich nur Generatoren erlaubt sein.
Verfasst: Sonntag 12. November 2006, 12:56
von Leonidas
TheGrudge hat geschrieben:aber dann besteht doch auch ein Iterator den Test, oder etwa nicht? Es sollen wirklich nur Generatoren erlaubt sein.
Iteratoren implementieren __iter__(), nicht next():
Code: Alles auswählen
In [44]: iter = xrange(5)
In [45]: iter.next()
---------------------------------------------------------------------------
<type 'exceptions.AttributeError'> Traceback (most recent call last)
/home/leonidas/<ipython console> in <module>()
<type 'exceptions.AttributeError'>: 'xrange' object has no attribute 'next'
Verfasst: Sonntag 12. November 2006, 12:57
von BlackJack
TheGrudge hat geschrieben:aber dann besteht doch auch ein Iterator den Test, oder etwa nicht? Es sollen wirklich nur Generatoren erlaubt sein.
Warum?
Verfasst: Sonntag 12. November 2006, 13:01
von BlackJack
Leonidas hat geschrieben:TheGrudge hat geschrieben:aber dann besteht doch auch ein Iterator den Test, oder etwa nicht? Es sollen wirklich nur Generatoren erlaubt sein.
Iteratoren implementieren __iter__(), nicht next():
Iteratoren implementieren `__iter__()`, das per Definition `self` zurückgeben sollte, und `next()`.
`xrange()` ist kein Iterator, sondern ein `iterable` oder etwas konkreter: es implementiert das `sequence`-Protokoll.
Verfasst: Sonntag 12. November 2006, 13:34
von mitsuhiko
Code: Alles auswählen
>>> from types import GeneratorType
>>> def foo():
... yield "blub"
...
>>> isinstance(foo(), GeneratorType)
True
Wenns wirklich nur ein Generator sein darf.
Verfasst: Sonntag 12. November 2006, 14:14
von TheGrudge
blackbird hat geschrieben:Code: Alles auswählen
>>> from types import GeneratorType
>>> def foo():
... yield "blub"
...
>>> isinstance(foo(), GeneratorType)
True
Wenns wirklich nur ein Generator sein darf.
Danke!
Verfasst: Montag 13. November 2006, 11:20
von Leonidas
BlackJack hat geschrieben:`xrange()` ist kein Iterator, sondern ein `iterable` oder etwas konkreter: es implementiert das `sequence`-Protokoll.
Ok, danke für die Klarstellung. Hast du auch noch irgendwelche weiteren Quellen, wo man sich über Datails informieren könnte?
Verfasst: Montag 13. November 2006, 11:34
von birkenfeld
http://svn.python.org/projects/python/t ... geobject.c
Man sieht: ein xrange-objekt implementiert sowohl das traditionelle sequence-Protokoll, stellt aber auch __iter__ zur Verfügung, was ein "rangeiterator"-Objekt erstellt, das zum Iterieren verwendet wird.
Verfasst: Montag 13. November 2006, 11:34
von BlackJack
Leonidas hat geschrieben:BlackJack hat geschrieben:`xrange()` ist kein Iterator, sondern ein `iterable` oder etwas konkreter: es implementiert das `sequence`-Protokoll.
Ok, danke für die Klarstellung. Hast du auch noch irgendwelche weiteren Quellen, wo man sich über Datails informieren könnte?
Du meinst ausser *den* Quellen, sprich Python-Quelltext?
Hauptsächlich Beobachtung, es verhält sich wie eine Sequenz und nicht wie ein Iterator:
Code: Alles auswählen
In [9]: a = xrange(0, 10, 2)
In [10]: a.
a.__class__ a.__init__ a.__repr__
a.__delattr__ a.__iter__ a.__reversed__
a.__doc__ a.__len__ a.__setattr__
a.__getattribute__ a.__new__ a.__str__
a.__getitem__ a.__reduce__
a.__hash__ a.__reduce_ex__
In [10]: len(a)
Out[10]: 5
In [11]: a[0]
Out[11]: 0
In [12]: a[2]
Out[12]: 4
In [13]: a[100]
---------------------------------------------------------------------------
exceptions.IndexError Traceback (most recent call last)
/home/marc/<ipython console>
IndexError: xrange object index out of range
Verfasst: Montag 13. November 2006, 14:16
von Leonidas
BlackJack hat geschrieben:Du meinst ausser *den* Quellen, sprich Python-Quelltext?
Exakt
Wobei das von birkenfeld gepostete rangeobject.c erstaunlich übersichtlich ist.
Aber danke fürs Codeschnippsel, hilft mir auch schon mal weiter.