global oder nicht global

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.
gNeandr
User
Beiträge: 68
Registriert: Sonntag 11. Mai 2014, 16:48

Hier wird in mehreren Beiträgen davon abgeraten 'global' einzusetzen.

Wenn Python 'global' definiert, dh. zulässt, warum sollte es nicht eingesetzt werden?
Für eine pro/con Aussage wäre ich dankbar :?:
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

gNeandr hat geschrieben:Wenn Python 'global' definiert, dh. zulässt, warum sollte es nicht eingesetzt werden?
Es liegt IMHO nicht in der Verantwortung einer Sprache, alles, von dem abgeraten wird, auch zu verbieten. Letztlich auch gar nicht möglich. Selbst wenn es das ``global`` Statement nicht gäbe, könnte man mit dem Rest noch genügend schlechten oder gar gefährlichen Code schreiben... :wink:

Von der Nutzung globaler Namen/Variablen wird ja nicht nur in Python, sondern auch in anderen Sprachen abgeraten.

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

gNeandr hat geschrieben:Wenn Python 'global' definiert, dh. zulässt, warum sollte es nicht eingesetzt werden?
Weil man nicht alles, was man tun kann, auch immer tun sollte.

Warum global oft eine schlechte Idee ist möchte ich hier nicht wiederkäuen, siehe die entsprechenden Beiträge, aber der Name deutet es schon an. Man sollte es nur und nur ausschließlich für die Verwaltung von globalen Zuständen verwenden und selbst da gibt es oft bessere Alternativen. global ist der "last resort". Genau wie goto in C.
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Goto kann den Code vereinfachen, global ist einfach nur schlechtes Design.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

gNeandr hat geschrieben:Wenn Python 'global' definiert, dh. zulässt, warum sollte es nicht eingesetzt werden?
Man schafft sich Abhängigkeiten die nach einiger Zeit nur noch schwer zu durchblicken sind. Ja, global kann durchaus mal nützlich sein, aber in über 99% der Fälle wo jemand es verwenden möchte ist der Einsatz nicht gerechtfertigt. Unter Python 3 gibt es noch nonlocal das nicht so dramatische Auswirkungen auf den globalen Namensraum hat.

Mal abgesehen davon, dass man global ohnehin möglichst nicht einsetzen sollte, muss man es im Eigeninteresse weglassen sobald man mit Threads zu tun hat. global ist nicht thread-safe.
BlackJack

Lesestoff zum Thema globale Variablen: http://c2.com/cgi/wiki?GlobalVariablesAreBad

Ist nicht speziell auf Python ausgerichtet sondern allgemein, darum sind einige Punkte, zum Beispiel was Linker in statisch typisierten Programmiersprachen angeht, nicht so einfach übertragbar, aber da ist auch genug allgemeines dabei.
gNeandr
User
Beiträge: 68
Registriert: Sonntag 11. Mai 2014, 16:48

@alle die geantwortet haben :D
Danke für den reichlichen Lesestoff .. werd es mir zu Gemüte führen
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

In Python führt global an Modulen eine Zustandsabhängigkeit ein - eine Sache die man zu 99,9% der Fälle definitiv nicht haben möchte. Da Python OOP und Closures kennt, hatt man doch viel mächtigere Werkzeuge zur Hand, mit denen man das erreichen kann und bei denen man als Programmierer auch erwartet, dass diese zustandsbehaftet sind bzw. sein können. Für Module gilt das nicht, von ``import ...`` bis zum Ende des Programmes sollten Module möglichst nebeneffektsfrei sein.
gNeandr
User
Beiträge: 68
Registriert: Sonntag 11. Mai 2014, 16:48

Also eher 'nicht global'.

Ich habe versucht eine allgemein gültige Handhabung von 'global's zu finden, wobei ich allerdings nicht in "Standard" Python recherchiert habe. Ergebnis eher mau :(

Eine Möglichkeit könnte sein:

Code: Alles auswählen

#  closure to handle global parameters
def gParam():
   parameter = {}
   def set(n, x):
      # just monitoring 
      print (n + " is:" + str(x))
      parameter[n] = x
   def get(n):
      return parameter[n]
   return set, get
gSet,gGet=gParam()
Dann kann ich an jeder Stelle im Code globals setzen bzw abfragen.

Code: Alles auswählen

gSet = ('parameterA', anyvalue)
localPa = gGet('parameterA')
Also ist dieser Weg OK, bessere Methode bekannt, evtl. weiterführende Links ?

Schönes Wochenende
Günter
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@gNeandr: Python kennt globale Variablen, man muß sich also keinen Workaround selber stricken. Besser wird die Benutzung von globalen Variablen dadurch definitiv nicht!
gNeandr
User
Beiträge: 68
Registriert: Sonntag 11. Mai 2014, 16:48

@Sirius3

... vielleicht hab ich den ganzen Thread falsch verstanden? ... oder wer?

Ja 'global's in Python gibt's keine Frage, aber auch Schwierigkeiten damit ... oder nicht? :?
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@gNeandr: Das Problem mit global ist nicht, dass es als syntaktisches Konstrukt irgendwie gefährlich wäre, sondern dass globaler Zustand in einem Programm schlecht ist. Ob man den globalen Zustand dann mittels des Keywords global oder mittels Closures einführt/verwaltet, ist Jacke wie Hose.
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
snafu
User
Beiträge: 6737
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Darii hat geschrieben:global ist der "last resort". Genau wie goto in C.
Dafür, dass ``goto`` ein "last resort" sein soll, wird es in echten Programmen - u.a. im C-Quelltext von Python und im Linux-Kernel - aber ganz schön oft verwendet. Wie passt das mit deiner Aussage zusammen? Sind das für dich allesamt schlechte Programmierer oder setzt du eine sehr spezielle Definition von "last resort" voraus?
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Globale Variablen ist in allen Programmiersprachen zu meiden egal ob nur lesend oder schreibend. Ein Workaround nur damit das Wort global nicht auftaucht, machts nicht besser. Nebenbei, dein Beispiel ist so wenig pythonisch, dass geht auch als Antipattern durch(Getter/Setter, Unnötige Klammern, Stringadditionen,...).
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
gNeandr
User
Beiträge: 68
Registriert: Sonntag 11. Mai 2014, 16:48

darktrym hat geschrieben:...
Nebenbei, dein Beispiel ist so wenig pythonisch, dass geht auch als Antipattern durch(Getter/Setter, Unnötige Klammern, Stringadditionen,...).
Gerne lerne ich dazu! In einem anderen Thread habe ich darauf hingewiesen, dass ich Python Neuling bin :lol:
Manches kommt halt aus meiner anderweitigen 'Vergangenheit' und dem 'Bedarf' nach Übersichtlichkeit (aber das ist sicher Geschmack & Gewohnheit)
Deshalb auch die Frage nach Links etc ... zb. wo finde ich gute Hinweise zu Getter/Setter in Python?
Benutzeravatar
snafu
User
Beiträge: 6737
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@gNeandr: Benenne doch mal konkret, wo du den Einsatz globaler Variablen benötigst. Ist dir z.B. klar, dass bei mehrfachen Importen des selben Moduls sich globale Zustandsveränderungen immer auf alle Stellen auswirken, wo das Modul benutzt wird? Ein ``import`` initialisiert ein Modul nämlich nur einmal. Nachfolgende Importe verwenden das bereits initialisierte Modul und damit auch dessen Zustand. Das kann zu äußerst merkwürdigem Verhalten führen. Beispiel:

Code: Alles auswählen

from __future__ import print_function

foo = 'foo'

def set_foo(value):
    global foo
    foo = value

def print_foo():
    print(foo)

Code: Alles auswählen

>>> import funwithfoo
>>> funwithfoo.print_foo()
foo
>>> funwithfoo.set_foo('bar')
>>> funwithfoo.print_foo()
bar
>>> import funwithfoo
>>> funwithfoo.print_foo()
bar
Es ist zwar ungewöhnlich, dass man im selben Modul ein anderes Modul mehrfach importiert, aber bei Projekten mit vielen Untermodulen kommt es ziemlich häufig vor, dass z.B. in mehreren Modulen das ``os``-Modul importiert wird. Und da kann einem dieses Verhalten durchaus um die Ohren fliegen.
Zuletzt geändert von snafu am Samstag 31. Mai 2014, 12:23, insgesamt 1-mal geändert.
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

gNeandr hat geschrieben:wo finde ich gute Hinweise zu Getter/Setter in Python?
Hier.
In specifications, Murphy's Law supersedes Ohm's.
gNeandr
User
Beiträge: 68
Registriert: Sonntag 11. Mai 2014, 16:48

@pillmuncher .. werde das mal durcharbeiten, Danke

@snafu
Die global Diskussion wurde angestoßen in diesem Thread:
http://www.python-forum.de/viewtopic.php?f=1&t=33895
Dort verwende ich verschiedene 'Parameter' in unterschiedlichen Routinen, aber das ganze wird (immer) ein einziges py Programm bleiben (soweit ich es momentan sehe)
BlackJack

@gNeandr: Eine allgemein gültige Handhabung dürfte sein statt globalen Zustand zu verwenden, den mit Argumenten/Parametern zu lokalem Zustand zu machen der herum gereicht wird.

Zum Closure: Anstelle eines solchen würde man in Python eine Klasse schreiben. Allerdings ist das ja letztendlich nur ein Wörterbuch, also könnte man auch gleich ein solches verwenden. Was wieder unschön ist, weil es ja eine globale Datenstruktur wäre.
Benutzeravatar
snafu
User
Beiträge: 6737
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Wenn man viele Werte herumreichen muss, aber Klassen einem noch zu hoch sind oder man die aus anderen Gründen nicht verwenden möchte, dann bietet Python diverse Möglichkeiten an: BlackJack hatte ja schon Wörterbücher genannt. Was noch geht, wären ``namedtuple``s oder ggf auch ``Namespace``-Objekte (wird von ``argparse`` so gemacht). Und die erstellt man dann natürlich nicht global, sondern lässt sich einmalig einen Kontext mit Default-Werten erzeugen ("options", "settings", "configuration", was-auch-immer), den man dann herumreichen kann.
Antworten