Seite 2 von 2

Re: Funktion mit Rückgabewert

Verfasst: Dienstag 15. Februar 2022, 20:01
von __blackjack__
Naja oder halt als „internal iterator“ das man die Teilergebnisse nicht beim Aufrufer verarbeitet, sondern eine Funktion mitgibt, die mit jedem Teilergebnis aufgerufen wird und die Verarbeitung übernimmt. Ist in Python halt unüblich weil die APIs in der Standardbibliothek und die Spracheigenschaften auf „external iterators“ ausgelegt ist. Ruby macht das ja beispielsweise anders herum.

Re: Funktion mit Rückgabewert

Verfasst: Mittwoch 16. Februar 2022, 08:23
von peterpy
Hallo PeterL (anderer Peter)
PeterL hat geschrieben: Dienstag 15. Februar 2022, 16:30 Hallo, aber wie soll der übergebene Wert zum Aufrufer zurückkommen ?
Die andere Funktion sendet doch sein das return zur aufrufenden Funktion ?
Bis dann.
Der Wert bleibt ja in der Funktion mit der for -Schleife erhalten.
Aber vielleicht willst Du den Wert in der Nebenfunktion manipulieren und mit return zurückgeben?
Die Neben-Funktion ist für deine "Echtzeit Betrachtung", Auflistung, Manipulation, Printausgabe, ...,
oder was auch immer Du willst. Und wenn das return in der Neben-Funktion steht, wird die for-Schleife nicht beendet.

Code: Alles auswählen

for zahl in range(10):
    pruefling = zahl / 3
    ergebnis = pruefe_ganzahl(pruefling)
    print(zahl, '|', pruefling)
    print(ergebnis)
    
def pruefe_ganzahl(pruefling):    
    if pruefling % 1 == 0:        
        return 'Ganzzahl'
    else:
        return 'Keine Ganzzahl'    
Gruss Peter

Re: Funktion mit Rückgabewert

Verfasst: Mittwoch 16. Februar 2022, 14:00
von DeaD_EyE
PeterL hat geschrieben: Montag 14. Februar 2022, 17:31 Wenn ich das Ergebnis mit return zurückgeben will.
Wird mir nur ein Ordner angezeigt. Mein Code:

Code: Alles auswählen

def ordner_unterordner_auslesen(quelle):
    for root, dirs, files in os.walk(quelle, topdown=True):
        for name in dirs:
            datei_pfad=(os.path.join(root,name)) 
            return datei_pfad
            

Ich habe jetzt nicht alle vorherigen Beiträge gelesen.

Im Endeffekt gibt es zwei Lösungsansätze.
Der erste Ansatz wäre es, eine Liste zu erstellen, die Ergebnisse zur Liste hinzufügen und dann die Liste mit return zurückgeben.
Der alternative Ansatz ist die Verwendung eines Generators:

Code: Alles auswählen

def ordner_unterordner_auslesen(quelle):
    for root, dirs, files in os.walk(quelle, topdown=True):
        for name in dirs:
            yield os.path.join(root,name)
In den vorherigen Beiträgen ist auch rglob vorgeschlagen worden, dass die Klasse Path als Methode anbietet.
Dann wird der Code etwas kürzer und ist besser lesbar.

Code: Alles auswählen

from pathlib import Path


def ordner_unterordner_auslesen(quelle):
    for path in Path(quelle).rglob("*"):
        if path.is_dir():
            yield path
Beide Funktionen sind GeneratorFunktionen und können so verwendet werden:

Code: Alles auswählen

unterordner = list(ordner_unterordner_auslesen("Downloads"))
Der Aufruf der GeneratorFunktion liefert einen Generator zurück.

Code: Alles auswählen

gen = ordner_unterordner_auslesen("Downloads")
Der Generator ist dem Namen gen zugewiesen und es passiert erst mal gar nichts.
Der Generator muss konsumiert werden. Das geht iterativ mit einer for-Schleife oder z.B. mit Typen, die ein iterierbare Objekte erwarten (list, tuple, set, frosenset, usw..)

Code: Alles auswählen

# Generator konsumieren
ergebnis = list(gen)


ergebnis2 = list(gen)
# ergebnis2 = [ ]
# liegt daran, dass der Generator bereits verbraucht ist
Die Verwendung eines Generators hat unter anderem den Vorteil, dass außerhalb der GeneratorFunktion bestimmt wird, in welcher Form die Ergebnisse gesammelt werden.

Re: Funktion mit Rückgabewert

Verfasst: Mittwoch 16. Februar 2022, 14:29
von __blackjack__
Wobei man bei den Generatorfunktionen hier auch eine ”normale” Funktion schreiben könnte, die einen Generatorausdruck verwendet um den Generator zu erstellen. Mal beispielhaft an der Variante mit `Path`, geht aber natürlich auch mit `os.walk()`-Variante:

Code: Alles auswählen

def ordner_unterordner_auslesen(quelle):
    return (path for path in Path(quelle).rglob("*") if path.is_dir())