Routineaufgaben mit Python automatisieren. Al Sweigart
Чтение книги онлайн.

Читать онлайн книгу Routineaufgaben mit Python automatisieren - Al Sweigart страница 56

Название: Routineaufgaben mit Python automatisieren

Автор: Al Sweigart

Издательство: Bookwire

Жанр: Математика

Серия:

isbn: 9783960889571

isbn:

СКАЧАТЬ die Formulierung gebraucht, dass eine Variable einen Wert enthält.

       Identität und die Funktion id()

      Vielleicht fragen Sie sich, warum das merkwürdige Verhalten, das Sie im vorhergehenden Abschnitt kennengelernt haben, nicht auch bei unveränderbaren Werten wie Integern oder Strings vorkommt. Um das besser zu verstehen, können wir die Python-Funktion id() heranziehen. Alle Werte in Python haben eine eindeutige Identität, die Sie mit dieser Funktion abrufen können. Geben Sie folgenden Code in die interaktive Shell ein:

      >>> id('Howdy') # Auf Ihrem Computer wird eine andere Zahl zurückgegeben

      44491136

      Wenn Python id('Howdy') ausführt, wird der String 'Howdy' im Arbeitsspeicher angelegt und die numerische Adresse seines Speicherorts zurückgegeben. Python wählt die Adresse danach aus, welche Bytes auf dem Computer gerade frei sind. Daher erhalten Sie jedes Mal, wenn Sie diesen Code ausführen, ein anderes Ergebnis.

      Wie alle Strings ist auch 'Howdy' unveränderbar. Wenn Sie einen String in einer Variablen ändern, wird in Wirklichkeit ein neues Stringobjekt an einer anderen Stelle im Arbeitsspeicher angelegt und der Verweis darauf in der Variablen festgehalten. Mit dem folgenden Beispielcode können Sie beobachten, wie sich die Identität des Strings ändert, auf den bacon verweist:

      >>> bacon = 'Hello'

      >>> id(bacon)

      44491136

      >>> bacon += ' world!' # Erstellt neuen String aus 'Hello' und ' world!'

      >>> id(bacon) # bacon verweist jetzt auf einen ganz anderen String

      44609712

      Listen dagegen sind veränderbar. Die Methode append() erstellt kein neues Listenobjekt, sondern verändert das vorhandene. Wir sprechen hier von einer unmittelbaren oder direkten Änderung des Objekts.

      >>> eggs = ['cat', 'dog'] # Erstellt eine neue Liste

      >>> id(eggs)

      35152584

      >>> eggs.append('moose') # append() ändert die Liste direkt

      >>> id(eggs) # eggs verweist immer noch auf dieselbe Liste

      35152584

      >>> eggs = ['bat', 'rat', 'cow'] # Erstellt eine neue Liste mit neuer

      Identität

      >>> id(eggs) # eggs verweist jetzt auf eine ganz andere Liste

      44409800

      Wenn zwei Variablen auf dieselbe Liste verweisen (wie spam und eggs im vorherigen Abschnitt) und die Liste geändert wird, dann sind davon beide Variablen betroffen. Die Listenmethoden append(), extend(), remove(), sort(), reverse() usw. ändern Listen direkt.

      Pythons automatische Garbage Collection entfernt alle Werte, auf die keine Variablen mehr verweisen, um Platz im Arbeitsspeicher freizumachen. Über diese Garbage Collection müssen Sie sich keine Gedanken machen, was eine gute Sache ist, denn durch die manuelle Speicherverwaltung in anderen Programmiersprachen schleichen sich häufig Fehler ein.

       Verweise übergeben

      Die Kenntnis von Verweisen ist unverzichtbar, um zu verstehen, wie Argumente an Funktionen übergeben werden. Bei einem Funktionsaufruf werden die Werte der Argumente in die Parametervariablen kopiert. Bei Listen als Argumenten (und bei Dictionaries, die ich im nächsten Kapitel beschreiben werde) bedeutet das, dass für den Parameter eine Kopie des Verweises verwendet wird. Um zu erkennen, was das bedeutet, geben Sie den folgenden Code im Dateieditor ein und speichern ihn als passingReference.py:

      def eggs(someParameter):

      someParameter.append('Hello')

      spam = [1, 2, 3]

      eggs(spam)

      print(spam)

      Beim Aufruf von eggs() wird kein Rückgabewert verwendet, um spam einen neuen Wert zuzuweisen. Stattdessen wird die Liste unmittelbar geändert. Dieses Programm führt zu folgender Ausgabe:

      [1, 2, 3, 'Hello']

      Obwohl spam und someParameter getrennte Verweise enthalten, verweisen doch beide auf dieselbe Liste. Daher wirkt sich der Methodenaufruf append('Hello') innerhalb der Funktion auch dann noch auf die Liste aus, wenn der Funktionsaufruf die Steuerung zurückgegeben hat.

      Merken Sie sich dieses Verhalten. Wenn Sie nicht beachten, dass Python Listen- und Dictionary-Variablen auf diese Weise handhabt, kann das zu verwirrenden Fehlern führen.

       Die Funktionen copy() und deepcopy() des Moduls copy

      Verweise zu übergeben ist oft die sinnvollste Vorgehensweise, wenn eine Funktion tatsächlich die übergebene Liste oder das Dictionary bearbeiten soll. Es kann jedoch auch vorkommen, dass Sie die ursprüngliche Liste bzw. das Dictionary nicht ändern wollen. Für diesen Fall stellt Python das Modul copy bereit, das die Funktionen copy() und deepcopy() enthält. Mit copy.copy() können Sie eine echte Kopie eines veränderbaren Wertes wie einer Liste oder eines Dictionarys erstellen, also nicht einfach nur eine Kopie des Verweises darauf. Geben Sie folgenden Code in die interaktive Shell ein:

      >>> import copy

      >>> spam = ['A', 'B', 'C', 'D']

      >>> id(spam)

      57205555

      >>> cheese = copy.copy(spam)

      >>> id(cheese) # cheese ist eine andere Liste mit eigener Identität

      57208888

      >>> cheese[1] = 42

      >>> spam

      ['A', 'B', 'C', 'D']

      >>> cheese

      ['A', 42, 'C', 'D']

      Hier verweisen die Variablen spam und cheese auf zwei unterschiedliche Listen, weshalb bei der Zuweisung von 42 zum Index 1 ausschließlich die Liste in cheese geändert wird. Wie Abb. 4–7 zeigt, verwenden die beiden Variablen nicht mehr dieselbe ID-Nummer, da sie nun auf verschiedene Listen verweisen.