1275 Stimmen

Wie erstelle ich eine Konstante in Python?

Wie deklariere ich eine Konstante in Python?

In Java machen wir:

public static final String CONST_NAME = "Name";

31voto

nvd Punkte 429

Eigenschaften sind eine Möglichkeit, Konstanten zu erstellen. Sie können dies tun, indem Sie eine Getter-Eigenschaft deklarieren, den Setter jedoch ignorieren. Zum Beispiel:

class MyFinalProperty(object):

    @property
    def name(self):
        return "John"

Sie können sich einen Artikel, den ich geschrieben habe, ansehen, um weitere Möglichkeiten zur Verwendung von Python-Eigenschaften zu finden.

20voto

hans_meine Punkte 1696

Neben den beiden Top-Antworten (Verwendung von Variablen mit GROSSBUCHSTABEN oder Verwendung von Eigenschaften, um die Werte schreibgeschützt zu machen) möchte ich erwähnen, dass es möglich ist, Metaklassen zu verwenden, um benannte Konstanten zu implementieren. Ich biete eine sehr einfache Lösung mit Metaklassen auf GitHub an, die hilfreich sein kann, wenn Sie möchten, dass die Werte informativer über ihren Typen/Namen sind:

>>> from named_constants import Constants
>>> class Colors(Constants):
...     black = 0
...     red = 1
...     white = 15
...
>>> c = Colors.black
>>> c == 0
True
>>> c
Colors.black
>>> c.name()
'black'
>>> Colors(0) is c
True

Dies ist etwas fortgeschritteneres Python, aber immer noch sehr einfach zu verwenden und praktisch. (Das Modul hat einige weitere Funktionen, einschließlich schreibgeschützter Konstanten, siehe das README.)

Es gibt ähnliche Lösungen in verschiedenen Repositories, aber meines Wissens fehlt es ihnen entweder an einer der grundlegenden Funktionen, die ich von Konstanten erwarten würde (wie Konstanz oder arbiträrer Typ), oder sie haben esoterische Funktionen hinzugefügt, die sie weniger allgemein anwendbar machen. Aber dies kann variieren, ich wäre dankbar für Feedback. :-)

19voto

doubleswirve Punkte 1308

Bearbeitung: Beispielcode für Python 3 hinzugefügt

Hinweis: diese andere Antwort scheint eine viel umfassendere Implementierung ähnlich der folgenden (mit mehr Funktionen) bereitzustellen.

Zuerst erstellen Sie eine Metaklasse:

class MetaConst(type):
    def __getattr__(cls, key):
        return cls[key]

    def __setattr__(cls, key, value):
        raise TypeError

Dies verhindert, dass statische Eigenschaften geändert werden. Erstellen Sie dann eine andere Klasse, die diese Metaklasse verwendet:

class Const(object):
    __metaclass__ = MetaConst

    def __getattr__(self, name):
        return self[name]

    def __setattr__(self, name, value):
        raise TypeError

Oder wenn Sie Python 3 verwenden:

class Const(object, metaclass=MetaConst):
    def __getattr__(self, name):
        return self[name]

    def __setattr__(self, name, value):
        raise TypeError

Dies sollte verhindern, dass Instanzeigenschaften geändert werden. Um es zu verwenden, erben Sie davon:

class MyConst(Const):
    A = 1
    B = 2

Jetzt sollten die Eigenschaften, die direkt oder über eine Instanz zugegriffen werden, konstant sein:

MyConst.A
# 1
my_const = MyConst()
my_const.A
# 1

MyConst.A = 'geändert'
# TypeError
my_const.A = 'geändert'
# TypeError

Hier ist ein Beispiel für die obige Anwendung. Hier ist ein weiteres Beispiel für Python 3.

17voto

Mike Amy Punkte 351

PEP 591 hat den 'final' Qualifikator. Die Durchsetzung liegt beim Typ-Checker.

Also kannst du machen:

MY_CONSTANT: Final = 12407

Hinweis: Das Final Schlüsselwort ist nur für Python 3.8 Version anwendbar

11voto

Garret Wilson Punkte 15709

Sie können ein benanntes Tupel als Workaround verwenden, um effektiv eine Konstante zu erstellen, die auf die gleiche Weise funktioniert wie eine statische endgültige Variable in Java (eine Java-"Konstante"). Als Workarounds gehen, ist es irgendwie elegant. (Ein eleganterer Ansatz wäre es, einfach die Python-Sprache zu verbessern --- welche Art von Sprache erlaubt es Ihnen, math.pi neu zu definieren? -- aber ich schweife ab.)

(Als ich das schreibe, bemerke ich, dass in einer anderen Antwort auf diese Frage bereits das benannte Tupel erwähnt wurde, aber ich werde hier fortsetzen, weil ich Ihnen eine Syntax zeigen werde, die näher an das herankommt, was Sie in Java erwarten würden, da Sie keinen benannten Typ erstellen müssen, wie es bei benannten Tupeln erforderlich ist.)

In Ihrem Beispiel werden Sie sich daran erinnern, dass wir in Java die Konstante innerhalb einer Klasse definieren müssen; da Sie keinen Klassennamen genannt haben, nennen wir sie Foo. Hier ist die Java-Klasse:

public class Foo {
  public static final String CONST_NAME = "Name";
}

Hier ist das Äquivalent in Python.

from collections import namedtuple
Foo = namedtuple('_Foo', 'CONST_NAME')('Name')

Der entscheidende Punkt, den ich hier hinzufügen möchte, ist, dass Sie keinen separaten Foo-Typ benötigen (ein "anonymes benanntes Tupel" wäre schön, obwohl das wie ein Widerspruch klingt), deshalb nennen wir unser benanntes Tupel _Foo, sodass es hoffentlich nicht in importierende Module entweichen wird.

Der zweite Punkt hier ist, dass wir sofort eine Instanz des benannten Tupels erstellen, und nennen es Foo; es ist nicht erforderlich, dies in einem separaten Schritt zu tun (es sei denn, Sie möchten). Jetzt können Sie in Python das gleiche tun wie in Java:

>>> Foo.CONST_NAME
'Name'

Aber Sie können ihm nichts zuweisen:

>>> Foo.CONST_NAME = 'bar'
…
AttributeError: kann Attribut nicht setzen

Anerkennung: Ich dachte, ich hätte den Ansatz des benannten Tupels erfunden, aber dann sehe ich, dass jemand anderes eine ähnliche (wenn auch weniger kompakte) Antwort gegeben hat. Dann habe ich auch bemerkt Was sind "benannte Tupel" in Python?, was darauf hinweist, dass sys.version_info jetzt ein benanntes Tupel ist, daher kam die Idee möglicherweise bereits viel früher aus der Python-Standardbibliothek.

Beachten Sie leider (da dies immer noch Python ist), dass Sie die gesamte Foo-Zuweisung vollständig löschen können:

>>> Foo = 'bar'

(facepalm)

Aber zumindest verhindern wir, dass der Wert von Foo.CONST_NAME geändert wird, und das ist besser als nichts. Viel Glück.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X