unittest - Prüfe auf Typ

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
TheGrudge
User
Beiträge: 96
Registriert: Donnerstag 4. Mai 2006, 18:39

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")
Benutzeravatar
TheGrudge
User
Beiträge: 96
Registriert: Donnerstag 4. Mai 2006, 18:39

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")
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

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
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
TheGrudge
User
Beiträge: 96
Registriert: Donnerstag 4. Mai 2006, 18:39

aber dann besteht doch auch ein Iterator den Test, oder etwa nicht? Es sollen wirklich nur Generatoren erlaubt sein.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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'
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

TheGrudge hat geschrieben:aber dann besteht doch auch ein Iterator den Test, oder etwa nicht? Es sollen wirklich nur Generatoren erlaubt sein.
Warum?
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.
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Code: Alles auswählen

>>> from types import GeneratorType
>>> def foo():
...  yield "blub"
... 
>>> isinstance(foo(), GeneratorType)
True
Wenns wirklich nur ein Generator sein darf.
TUFKAB – the user formerly known as blackbird
Benutzeravatar
TheGrudge
User
Beiträge: 96
Registriert: Donnerstag 4. Mai 2006, 18:39

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!
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

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.
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
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten