leeres Set, abfrage mit if/else schlägt fehl

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
Back2basic
User
Beiträge: 23
Registriert: Montag 23. April 2012, 09:53

Hallo,

hab mal ne Anfängerfrage :-)

und zwar geht die Methode bzw. die Funktion nicht in meinen Else Zweig, trotz der leeren Menge ...

Code: Alles auswählen

if myCursor:
            for datensatz in myCursor:
                print strdatensatz
        else:
                print("Keine fehlerhaften Eintraege/Tage")

        myCursor.close()
In myCursor sollte nichts drin sein, leider geht diese Abfrage dann nicht in den anderen Zweig.
webspider
User
Beiträge: 485
Registriert: Sonntag 19. Juni 2011, 13:41

Deine Einrückung passt nicht (in anderen Programmiersprachen wäre das unproblematisch, aber in Python nicht, da sie dort elementarer Bestandteil ist um Blöcke zu kennzeichnen). Achte darauf deinen Editor so einzustellen, dass er keine Tabulatoren ausgibt, sondern stattdessen um vier Leerzeichen einrückt. Hier mal ein vereinfachtes interaktives Beispiel:

Code: Alles auswählen

>>> a = [1, 2]
>>> b = []
>>> if a:
...     for element in a:
...         print element
... else:
...     print "Empty iterable"
... 
1
2
>>> if b:
...     for element in b:
...         print element
... else:
...     print "Empty iterable"
... 
Empty iterable
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

myCursor ist wahrscheinlich kein Set, sondern ein Iterator. Dieser steht nicht als Wahrheitswert für seinen Inhalt, d.h. ist nicht falsch, wenn der nächste Aufruf von next() zu einer StopIteration führen würde. Das geht prinzipiell nicht, denn dazu müsste der Iterator ja iterieren, was zu einem Seiteneffekt führen könnte, den man nicht haben will. Mindestens wird ein Element "verbraucht".

Code: Alles auswählen

>>> a = iter([])
>>> bool(a)
True # und nicht False wie man erwarten könnte
Mache es so:

Code: Alles auswählen

empty = True
for e in a:
    empty = False
    ...
if empty:
    ... 
Stefan
Back2basic
User
Beiträge: 23
Registriert: Montag 23. April 2012, 09:53

@ sma

oh hab nicht gesehen das der Quellcode teils gestreckt wurde durch das kopieren. Soweit ich aber bei mir sehen kann ist der Zweig korrekt eingerückt.

@ stefan

es hat funktioniert, vielen Dank. Aber wieso myCursor ein iterator ist bleibt mir immer noch schleierhaft. in mycursor steckt ja mein request quasi.

In der for Schleife gehe ich ja dann durch mit datensatz in myCursor.

Für mich wäre der datensatz mein iterator :-O

Vielen Dank euch beiden für die schnelle Hilfe. Ein problem weniger ...
BlackJack

@Back2basic: In `my_cursor` steckt nicht Deine Anfrage sondern das Ergebnis. Das ist ein Datentyp der es erlaubt über die Ergebnisse einer Anfrage zu iterieren. Um mal Wikipedia zu zitieren: „The database cursor characteristic of traversal makes cursors akin to the programming language concept of iterator.” Cursor (databases)

Du solltest Deine Terminilogie besser der Realität anpassen. :-) Iterator ist das Objekt aus dem man die Elemente holt, und nicht die Elemente die man aus — ja wie würdest Du denn dann einen Iterator nennen?
Back2basic
User
Beiträge: 23
Registriert: Montag 23. April 2012, 09:53

ahhh falsch geschrieben, mit dem request mein ich natürlich meine menge wo meine daten aus der datenbank
alle enthalten sind.

Der Iterator für mich ist eine Art Zeiger, der mich über die Menge meiner Datensätze leitet.

Quasi mein i in einer for schleife ^^

Der Itarator ist selber nicht die Menge, sondern nur der Zeiger der auf ein aktuelles Objekt in der Menge zeigt.

Sehe ich das jetzt falsch ?
BlackJack

@Back2basic: Der Iterator kann intern so etwas wie ein Zeiger in eine Folge von existierenden Datensätzen sein (muss er aber nicht!). Aber das ist nicht das `i` in einer ``for``-Schleife. Das `i` wird an die Elemente gebunden, die der Iterator liefert wenn `next()` auf dem Iterator aufgerufen wird. Iteratoren sind die Objekte die das entsprechende Protokoll implementieren, also mit `next()` das jeweils nächste Element liefern oder eine `StopIteration`-Ausnahme auslösen falls es kein nächstes Element gibt.

Hinter dem ``in`` einer ``for``-Schleife muss ein iterierbares Objekt stehen, also eines, das wenn man es an die `iter()`-Funktion übergibt, einen Iterator liefert. Der wird intern für jeden Schleifendurchlauf nach dem nächsten Element gefragt, und das wird an den oder die Namen zwischen ``for`` und ``in`` gebunden. Die folgende ``for``-Schleife müsste man durch die danach folgende ``while``-Schleife ersetzen, wenn es ``for`` in Python nicht gäbe:

Code: Alles auswählen

for item in iterable:
    do_somethint(item)

# ->

iterator = iter(iterable)
while True:
    try:
        item = iterator.next()
    except StopIteration:
        break
    else:
        do_something(item)
Wobei man auf den Iterator einer ``for``-Schleife normalerweise keinen direkten Zugriff hat. Wenn man das möchte, muss man den Iterator *vor* der ``for``-Schleife selber erstellen und ihn als `iterable` nach dem ``in`` angeben. Den Iteratoren sind selbst iterierbar. Die Sprachbeschreibung gibt an, dass ein Iterator bei ``iter(iterator)`` unverändert zurück gegeben wird.
Antworten