Konstanten

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
pepe-je
User
Beiträge: 1
Registriert: Samstag 16. Dezember 2006, 15:31

Ein Python-Anfänger hat eine Frage.
Kann man erreichen, dass eine Variable nach Zuweisung eines Anfangswertes nicht mehr verändert werden kann?
In Java geht das durch das vorangestellte Attribut "final",
z.B. final int x = 5;
Gibt es so eine Möglichkeit auch in Python?
BlackJack

Man benutzt einen Namen in Grossbuchstaben, die Konvention für "Konstanten", und bindet den Namen einfach nicht neu.

Ansonsten solltest Du über das Datenmodell von Python nachdenken: In Python gibt's Namen die man an Objekte binden kann. Die Objekte wissen nichts über die Namen und Namen kennen den Typ von Objekten nicht. Namen bezeichnen keinen festen Speicherplatz der einen Typ hat.
lunar

Python ist dynamisch. Da ist nichts konstant; du kannst vielmehr alles (sogar Methoden von Objekten) zu Laufzeit ändern...

Das einzige, was du machen kannst, ist ein Attribut definieren und dich selbst dazu zwingen, den Wert dieses Attributes nie zu veränden...
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

pepe-je hat geschrieben:Kann man erreichen, dass eine Variable nach Zuweisung eines Anfangswertes nicht mehr verändert werden kann?
Hi pepe-je!

Es gibt eine Schreibweise, an die man sich im Python halten sollte:

Wenn ein Variablenamen GROSS geschrieben wird, dann stellt dieser eine Konstante dar. Dieser sollte nicht mehr überschrieben werden. Wenn du dann im Code eine groß geschriebene Variable überschreibst, dann bist du selber schuld.

Code: Alles auswählen

ANFANGSWERT = 1
Es gibt mehrere programmierbare Möglichkeiten, Konstanten nachzubilden, aber dieser Aufwand rentiert sich in keinem mir bekannten Fall.

Z.B. so: http://aspn.activestate.com/ASPN/Cookbo ... cipe/65207

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Python hat eine andere Programmierphilosophie als Java. Java ist sehr ausführlich und gibt einem Programmierer viele Möglichkeiten, sich selbst und anderen Schranken zu setzen. Python geht davon aus, das ein Programmierer weiss, was er tut: Ich würde das mal mit "Nur weil es geht, heisst es nicht, dass man es machen sollte" umschreiben. Java geht da eher den Weg "Wenn es geht, kannst du es machen"


Die Programmierphilosophie ist auch gut im Zen of Python zusammengefasst, dieses bekommst du, wenn du im Interpreter "import this" eingibst. Meiner Meinung nach sollte es jeder Anfänger gelesen (und verstanden) haben, dann wird einem klarer, warum was in Python so und nicht anders geregelt ist.
import this hat geschrieben:The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
gagei
User
Beiträge: 3
Registriert: Freitag 5. Januar 2007, 14:57

Hallo,

wie verwendet man solche per Großbuchstaben als Quasi-Konstante definierte Variablen innerhalb von Funktionen im Sinne eines guten Programmierstils?

1. Per global-Anweisung als globale Variable?
-> gefällt mir nicht wirklich

Code: Alles auswählen

A=5
B=7

def func():
    global A, B
    print A, B

func()
2. Als Funktionsparameter?
-> kann bei vielen Konstanten unübersichtlich werden

Code: Alles auswählen

A=5
B=7

def func(A, B):
    print A, B

func(A, B)
3. Man kapselt die Konstanten in einer Klasse und verwendet diese ohne global-Anweisung.

Code: Alles auswählen

class CONST:
    A=5
    B=7

def func():
    print CONST.A, CONST.B

func()
4. man kapselt die Konstanten in einer Klasse und übergibt
diese als Funktionsparameter

Code: Alles auswählen

class CONST:
    A=5
    B=7

def func(CONST):
    print CONST.A, CONST.B

func(CONST)
4a. Wie 4. ohne Verwendung des gleichen Bezeichners:

Code: Alles auswählen

class CONST:
    A=5
    B=7

def func(C):
    print C.A, C.B

func(CONST)
Oder noch anders?

Gruß,

Ingo Rogalsky
BlackJack

Du hast ja alles durch, ausser das einfachste:

Code: Alles auswählen

A = 42

def f():
    print A
``global`` brauchst Du nur wenn Du einen Namen ausserhalb der Funktion neu binden willst. Das ist bei Konstanten ja nun überhaupt nicht der Fall. :-)

Wenn man ``global`` für den Lesezugriff bräuchte, müsste man ja auch alle Funktionsnamen als ``global`` deklarieren, die man innerhalb einer Funktion benutzt. Was die Sichtbarkeit von Namen angeht, macht es keinen Unterschied an was für ein Objekt der Name gebunden ist, ob nun eine Funtkion oder eine Zahl, das ist egal, die Regeln bleiben die gleichen.
gagei
User
Beiträge: 3
Registriert: Freitag 5. Januar 2007, 14:57

BlackJack hat geschrieben:Du hast ja alles durch, ausser das einfachste:

Code: Alles auswählen

A = 42

def f():
    print A
Ja klar, diese Variante habe ich vergessen aufzuführen. In der Tat habe ich diese bisher auch häufig so verwendet. Meist verwende ich aber Funktionsparameter. Dies wird bei vielen Konstanten aber unübersichtlich. Daher war ich auf der Suche nach einer anderen sauberen Variante. Meine Frage bezog sich primär auf den guten Programmierstil. Und da möchte ich globale Variablen (was ja diese Großbuchstaben-KONSTANTEN eigentlich sind) vermeiden.

Dass es eine global-Definition gibt, hatte ich schon längst wieder vergessen (und dies ist wohl auch gut so). Darauf bin ich vorhin bloß beim Suchen nach einer Antwort auf meine Frage aufmerksam geworden.

Gruß, Ingo
Benutzeravatar
Luzandro
User
Beiträge: 87
Registriert: Freitag 21. April 2006, 17:03

gagei hat geschrieben:Meine Frage bezog sich primär auf den guten Programmierstil. Und da möchte ich globale Variablen (was ja diese Großbuchstaben-KONSTANTEN eigentlich sind) vermeiden.
ja, nur wenn man sich an die Konvention hält, sind es ja eben keine globalen Variablen sondern globale Konstanten, was ja üblicherweise Sinn macht, bzw. eigentlich bezieht sich 'global' auch nur auf das entspr. Modul und bei imports musst du den Namespace angeben (wenn du nicht sowas wie 'from A import *' machst, aber nachdem du hier nach Stil fragst, hast du das hoffentlich nicht vor ;) )
[url=http://www.leckse.net/artikel/meta/profilieren]Profilieren im Netz leicht gemacht[/url]
hackepeter
User
Beiträge: 3
Registriert: Mittwoch 3. Januar 2007, 13:18
Wohnort: München

gagei hat geschrieben:Hallo,

wie verwendet man solche per Großbuchstaben als Quasi-Konstante definierte Variablen innerhalb von Funktionen im Sinne eines guten Programmierstils?
...
Oder noch anders?

Gruß,

Ingo Rogalsky
Bei vielen Varianten kann man tatsächlich "echte" Konstanten wie folgt erzeugen (Beispiel):

Code: Alles auswählen

class consttest(object):

	def __init__(self):
		self.__ConstVar = 1

	def getConstVar(self):
		return self.__ConstVar

	ConstVar = property(fget=getConstVar)


if __name__ == '__main__':
	c = consttest()

	print c.ConstVar
	c.ConstVar = 5 # Fehler!
	print c.ConstVar
Erklärung: "property" erzeugt einen Namen und bindet den an get/set Methoden. Ist keine set-Methode definiert, krachts.

Gruß HP
BlackJack

Ist aber unnötig kompliziert. Wer Namen, die komplett in Grossbuchstaben geschrieben sind, neu bindet, sollte halt nicht programmieren oder muss mit den Konsequenzen leben.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hi!

Viele stellen sich das schwieriger vor, als es im Endeffekt ist. Ich komme von Visual Basic 6 und suchte auch zuerst krampfhaft nach solchen Dingen wie ``CONST`` oder klaren Typzuweisungen.

Je mehr ich Python verstand, desto weniger stand mir der Sinn nach diesen Überbleibseln.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-

LOG_FILENAME = "my_logfile.log"


def log(message):
    f = file(LOG_FILENAME, "a")
    f.write(message + "\n")
    f.close()


log("Hallo")
log("Welt")
Kein Python-Programmierer würde auf die Idee kommen, nochmal irgendwo im Code ``LOG_FILENAME = "nocheinlogfile.log"`` zu schreiben. Die Großschreibung genügt vollkommen. Das ist genau so wie bei den Namen, die mit einem Unterstrich beginnen (``_nur_direkt_auf_mich_zugreifen_wenn_du_weisst_was_du_tust``).
Der Unterstrich bedeutet schlicht und einfach, dass es sich hier um etwas privates handelt. Man soll nicht direkt darauf zugreifen -- "außer" man weiß was man tut. Das ist so ausgemacht. Schluss, aus, fertig!

- Großgeschriebenen Bezeichner sind KONSTANTEN und dürfen nicht überschrieben werden. (Außer du weißt was du tust.)

- Ein Unterstrich an erster Stelle eines Bezeichners bedeutet PRIVAT.

- Eine Funktion oder Methode wird mit ``def`` eingeleitet

- Bei Klassennamen schreibt man den ersten und evt. noch ein paar andere Buchstaben im Bezeichner groß.

- Funktions-/Methodennamen beginnen mit einem kleinen Buchstaben.

- Python ist eine Programmiersprache und keine Schlange

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Antworten