Seite 1 von 2

Problem mit globalen und lokalen Werten

Verfasst: Samstag 27. November 2010, 23:20
von AchtungHuPe
Hallo,
ich bin dabei mir rein hobbymäßig Python beizubringen und gleichzeitig auch meinem Sohn einen Einstieg ins programmieren zu zeigen.
Bei einer Sache stehe ich jetzt aber an: Warum liefert die Funktionen den veränderten Wert von anzahl nicht?
Zur Veranschaulichung mal das ganze Programm auf's notwendigste gekürzt.

Code: Alles auswählen

liste =[['.','.'] , ['.','.']]
anzahl = 0

def listemod(anzahl):
    liste[0][1] = 'X'
    anzahl += 1
    print('anzahl (inside):',anzahl)
    return anzahl


# main
print('Liste vorher:', liste)
print('anzahl (outside):',anzahl)
listemod(anzahl)
print('Liste nachher:', liste)
print('anzahl (outside):',anzahl)
Probelauf

Code: Alles auswählen

>>> 
Liste vorher: [['.', '.'], ['.', '.']]
anzahl (outside): 0
anzahl (inside): 1
Liste nachher: [['.', 'X'], ['.', '.']]
anzahl (outside): 0
>>> 
Neben dem aktuellen Problem außerhalb der Funktion nicht den geänderten Wert von anzahl zu haben, verstehe ich nicht warum dagegen das ändern eines Listenwertes ohne weiteres Tamtam (Parameterübergabe, return) so einfach funktioniert.

Was ist falsch oder besser wie gehts richtig?

Re: Problem mit globalen und lokalen Werten

Verfasst: Samstag 27. November 2010, 23:49
von cofi
Listen sind veraenderbar, Zahlen nicht.
Das ist nicht das Problem, sondern ist fuer das Phaenomen verantwortlich - zumindest waer das der Fall, wenn der Funktionsparameter anders heissen wuerde. Man kann globalen (oder aeusseren) Namen keine neuen Objekte zuweisen ohne `global' (oder `nonlocal') zu verwenden. Die Liste wird aber wie gesagt direkt veraendert.

`anzahl' betritt die Funktion als Parameter, nicht als der globale Namen, darum kann sich der globale Namen gar nicht veraendern, weil auf ihn gar nich zugegriffen wird. `print(listemod(anzahl))` wird dir auch 1 ausgeben. Genauso wird `anzahl = listemod(anzahl)' funktionieren.

P.S. Man sollte das Veraendern globalen Objekten moeglichst vermeiden (`global' erst recht)

Re: Problem mit globalen und lokalen Werten

Verfasst: Samstag 27. November 2010, 23:51
von BlackJack
@AchtungHuPe: Die Funktion gibt den Wert zurück -- Du machst dann aber nichts damit. Du müsstest ihn auch wieder an das globale `anzahl` zuweisen:

Code: Alles auswählen

anzahl = listemod(anzahl)
Bei der Liste veränderst Du das Listenobjekt. Das ist etwas anderes als die Bindung zwischen Name und Objekt zu ändern. `liste` ist vor und nach dem Aufruf von `listemod()` immer an das selbe Listenobjekt gebunden. Genau wie in Deinem Beispiel `anzahl` an das selbe Objekt gebunden ist. Im Gegensatz zu Listen kann man Zahlen aber nicht verändern.

Re: Problem mit globalen und lokalen Werten

Verfasst: Sonntag 28. November 2010, 00:17
von AchtungHuPe
Danke für die Antworten, das ist für mich nachvollziehbar und verständlich.

@cofi: Auf `anzahl = listemod(anzahl)' " bin ich in der Zwischenzeit durch grübeln auch gekommen.
Bei der Recherche habe ich über global folgendes gelesen und es war so überzeugend, dass ich ohne auskommen wollte
Alles was von einer Funktion zum Arbeiten benötigt wird, sollte man an
die Funktion als Parameter übergeben.

Alles was von einer Funktion verändert werden soll, sollte man als
Rückgabe (mit return) zurück geben.

So wird kein "global" gebraucht und alles was passiert ist
offensichtlicher denn je. Schon beim Aufruf der Funktion ist klar, dass
die Variable "my_value" mit einem neuen Wert belegt wird. Man muss sich
dazu die Funktion nicht durchlesen.
@all: Im richtigen Programm ist der Hauptzweck der Funktion die Liste zu verändern. Der Zähler ist nur ein Nebenprodukt um eine bestimmte Bedingung zu prüfen.

So war es gedacht:

Code: Alles auswählen

while spiel =='begonnen':
    benutzereingabe()
    computerzug()
Mit o.a. Zuweisung funktioniert es zwar aber das führt dabei zu Code der, zumindest auf mich, seltsam wirkt

Code: Alles auswählen

while spiel == 'begonnen':
    anzahl = spielerzug(anzahl)
    anzahl = computerzug(anzahl)
Die zweite Variante ist schon übler Stil, oder?
Also doch die global-Variable oder ein ganz anderer Ansatz. Ich könnte statt dem Zähler eine weitere Liste manipulieren, die hätte dann nur ein Element das als 'Zählvariable' verwendet wird. Ist das wirklich besser?

Re: Problem mit globalen und lokalen Werten

Verfasst: Sonntag 28. November 2010, 00:23
von cofi
AchtungHuPe hat geschrieben:Bei der Recherche habe ich über global folgendes gelesen und es war so überzeugend, dass ich ohne auskommen wollte
Meine Erwaehnung von `global` war auch keinesfalls eine Empfehlung, sondern ich habs zur Illustration benutzt. Wenn man `global` nutzt, macht man zu 99,9% etwas falsch und den Rest kann man auch anders abdecken.

Code: Alles auswählen

while spiel == 'begonnen':
    anzahl = computerzug(spielerzug(anzahl))
Aber das ruft fuer mich lautstark nach Klassen.

Edit: `spiel` laesst sich doch bestimmt besser durch False/True ausdruecken oder?

Re: Problem mit globalen und lokalen Werten

Verfasst: Sonntag 28. November 2010, 09:34
von AchtungHuPe
Bei Klassen bin ich noch nicht angekommen :(

Die Sache mit dem Zähler funktioniert nun. Ich lasse `anzahl´nicht innerhalb der Funktion mitlaufen sondern beim aufrufen der Funktion in der Hauptschleife, das ist hier zulässig. Alternativ kann man es auch mit einer Scheife realisieren, glaube bin gestern voll auf der Leitung gestanden was das betrifft :-/

Momentan beschäftige ich mich mit dem Spielende. `spiel´ habe ich auf boolen umgestellt. Die Funktion zum auswerten des Zuges erkennt zwar die Gewinnsituation aber die Hauptschleife stoppt trotzdem nicht. Wahrscheinlich ein ähnliches Problem wie oben nur ohne Fehlermeldung. Da komme ich jetzt schon selber dahinter ;-)


Muss mich nochmal bedanken für die raschen und guten Antworten, hat mir sehr geholfen!

Re: Problem mit globalen und lokalen Werten

Verfasst: Sonntag 28. November 2010, 09:45
von funkheld
Mit Python kannst du keinen einen Einstieg in das Programmieren zeigen ,das wird ein Irrgarten.
Python ist eine Scriptsprache mit der man nur durch die Brust ins Auge etwas vernünftiges Zaubern kann.
Wenn du anderen erzählst, mit was du proggen tust und dann "Python" nennst, bekommst du nur ein müdes lächeln zurück. :D

Python ja, nur wenn man programmieren kann , ansonsten Finger weg.
90% der Begriffe von Python sind in der allgemeinen Programmierumgebung unbekannt.

Ich kann als Sprache XBLite empfehlen.

Gruss

Re: Problem mit globalen und lokalen Werten

Verfasst: Sonntag 28. November 2010, 11:43
von sma
Im Gegensatz zu funkheld halte ich Python durchaus für eine gerade auch für Anfänger geeignete Sprache. Das 90% irgendwelcher Begriffe anders sein sollten, halte ich für falsch. Die Unterscheidung zwischen Script- und Programmiersprache ist künstlich und irrelevant. Ich persönlich finde Python auch von der Syntax her einfacher und eleganter als ein Basic-Dialekt.

Das Scoping von Variablen ist bei Python zugegeben ungewöhnlich (aber schlüssig). Darüber ist AchtungHuPe ja schon gestolpert. Die meisten Sprachen folgen hier dem Prinzip der lexikografischen Bindung. Die restliche Semantik ist wie bei allen anderen imperativen Sprachen - keine Überraschungen. Python erlaubt neben einfacher prozeduraler Programmierung auch Ausflüge in die objektorientierte und (mit etwas Selbstbeschränkung) die funktionale Programmierung.

Stefan

Re: Problem mit globalen und lokalen Werten

Verfasst: Sonntag 28. November 2010, 14:25
von Darii
funkheld hat geschrieben:90% der Begriffe von Python sind in der allgemeinen Programmierumgebung unbekannt.
Aha. Beispiele?

Re: Problem mit globalen und lokalen Werten

Verfasst: Sonntag 28. November 2010, 22:53
von jbs
funkheld hat geschrieben: Wenn du anderen erzählst, mit was du proggen tust und dann "Python" nennst, bekommst du nur ein müdes lächeln zurück. :D
Meist von von Leuten, die mit PHP zu tun haben...

Ich fang mal an: 9 Sachen, die es "nur" in Python gibt:

1. Einrückung durch Whitespace
2. Explizit ist besser als Implizit
...

Re: Problem mit globalen und lokalen Werten

Verfasst: Sonntag 28. November 2010, 23:31
von AchtungHuPe
Hallo funkheld,

"Einstieg in Programmierung"

Danke für Deinen, sicher gut gemeinten, Tip zu XBLite.
Andererseits möchte ich meinen 13-jährigen jetzt ja nicht zum Profihacker ausbilden der vom coden lebt ....

Es geht mir vielmehr darum ihm zu zeigen was Programmieren eigentlich ist. Also Probleme/Aufgabenstellungen systematisch in Teile zerlegen, zu hinterfragen ob die Aufgabenstellung vollständig ist (und zu erkennen was fehlt) sowie ein Werkzeuge zur Umsetzung anzuwenden lernen.
Mit Python kann ich genausogut prozedural an Aufgaben herangehen, Datentypen und Ablaufsteuerung erklären und über Funktionen mich dem Wesen der Objektorientierung nähern.

Dafür war Python bis jetzt nicht die schlechteste Wahl. Ist cool zuzusehen wie er versteht warum was nicht funktioniert weil zB wiedermal die " ' " um einen String fehlten oder auch dass er manchmal pragmatischere Ansätze findet als ich selber :D

Re: Problem mit globalen und lokalen Werten

Verfasst: Sonntag 28. November 2010, 23:56
von Darii
AchtungHuPe hat geschrieben:Danke für Deinen, sicher gut gemeinten, Tip zu XBLite.
Andererseits möchte ich meinen 13-jährigen jetzt ja nicht zum Profihacker ausbilden der vom coden lebt ....
Lass dich bitte nicht von funkheld verwirren. XBlite kennt keiner, benutzt keiner und viel schlimmer gibts das nur für Windows. Vermutlich einer der letzten Basic-Dialekte den ich irgendwem als Einstieg empfehlen würde. Je weniger esoterisch die Sprache ist, desto mehr Doku und Hilfe findet man i.d.R.

Re: Problem mit globalen und lokalen Werten

Verfasst: Montag 29. November 2010, 11:31
von numerix
AchtungHuPe hat geschrieben:Andererseits möchte ich meinen 13-jährigen jetzt ja nicht zum Profihacker ausbilden der vom coden lebt ....
Evtl. wäre das was für euch: Python für Kids. In der aktuellen Auflage sogar schon für Python 3.1. Der Zugang über die Turtle-Grafik kann gerade für junge Programmierer motivierend sein. Ähnlich (allerdings ohne Buch, dafür mit kostenlosem dt. Tutorial): Das frog-Modul.

Re: Problem mit globalen und lokalen Werten

Verfasst: Montag 29. November 2010, 13:08
von sma
jbs hat geschrieben:Ich fang mal an: 9 Sachen, die es "nur" in Python gibt:

1. Einrückung durch Whitespace
Mir fällt spontan Occam ein, eine Sprache aus den 80ern (noch vor Python), die Einrückung für Blöcke nutzte. Und ohne das jetzt nachzugucken, Haskell kann das doch alternativ zu Klammern ebenfalls.

Also nur noch 8 Sachen...

Stefan

Re: Problem mit globalen und lokalen Werten

Verfasst: Montag 29. November 2010, 13:16
von BlackJack
Nemerle und CoffeScript würden mir da noch zusätzlich einfallen.

Re: Problem mit globalen und lokalen Werten

Verfasst: Montag 29. November 2010, 14:31
von jbs
sma hat geschrieben:
jbs hat geschrieben:Ich fang mal an: 9 Sachen, die es "nur" in Python gibt:

1. Einrückung durch Whitespace
Mir fällt spontan Occam ein, eine Sprache aus den 80ern (noch vor Python), die Einrückung für Blöcke nutzte. Und ohne das jetzt nachzugucken, Haskell kann das doch alternativ zu Klammern ebenfalls.

Also nur noch 8 Sachen...

Stefan
Deshalb steht das `nur` auch in `"`.

Re: Problem mit globalen und lokalen Werten

Verfasst: Dienstag 30. November 2010, 20:53
von Leonidas
BlackJack hat geschrieben:Nemerle und CoffeScript würden mir da noch zusätzlich einfallen.
Außerdem Haml und Jade.

Und explizit ist besser als implizit gibts auch in Java, einer der bekanntesten Programmiersprachen überhaupt. Also nur noch 7 Sachen, bin gespannt auf den Rest der Liste.

Re: Problem mit globalen und lokalen Werten

Verfasst: Dienstag 30. November 2010, 21:40
von sma
Für HAML, Jade und CoffeeScript gilt aber, dass die allesamt nach Python erfunden wurden, zum Teil sogar Python als Inspirationsquelle nennen. Daher nannte ich extra Occam. Zu "explizit vs. implizit" wollte ich nichts sagen, denn das ist weniger ein Feature als eine Philosophie. Und hier gibt es wohl eher den Streit zwischen "es gibt einen Weg" und "es gibt mehrere Wege" (MTOWTDI oder so) Denkschulen, den man besser eindeutig auf Sprachen und ihr Erscheinungsdatum abbilden kann. Scheme war z.B. auch Reaktion auf die Vielfalt von Lösungswegen in CommonLisp. Dennoch ist Perl das poster child für MTOWTDI.

Aber wo bleiben Sie denn nun, die besonderen Eigenschaften von Python? List comprehensions sind es schon mal nicht. Objektorientierung auch nicht. Lambda jedenfalls nicht, das gab es auch schon in den frühsten Lisp-Dialekten. Möglicherweise der "if/else"-Operator, den hatte ich vor Python so noch in keiner anderen Sprache gesehen. Alle anderen stellen immer die Bedingung nach vorne.

Stefan

Re: Problem mit globalen und lokalen Werten

Verfasst: Dienstag 30. November 2010, 23:14
von bords0
jbs hat geschrieben:Ich fang mal an: 9 Sachen, die es "nur" in Python gibt:

1. Einrückung durch Whitespace
2. Explizit ist besser als Implizit
...
Äh, mit was rücken denn die anderen Sprachen ein? Blackspace?

Re: Problem mit globalen und lokalen Werten

Verfasst: Dienstag 30. November 2010, 23:23
von ms4py
bords0 hat geschrieben:
jbs hat geschrieben:Ich fang mal an: 9 Sachen, die es "nur" in Python gibt:

1. Einrückung durch Whitespace
2. Explizit ist besser als Implizit
...
Äh, mit was rücken denn die anderen Sprachen ein? Blackspace?
In der Regel (u. a. Java, C, C++, C#) werden Blöcke mit { } markiert. Einrückung ist völlig egal..