Importieren einer langen Liste von Konstanten in eine Python-Datei

88

Gibt es in Python ein Analogon zur CPräprozessoranweisung wie?:

#define MY_CONSTANT 50

Außerdem habe ich eine große Liste von Konstanten, die ich in mehrere Klassen importieren möchte. Gibt es ein Analogon zum Deklarieren der Konstanten als lange Folge von Anweisungen wie oben in einer .pyDatei und zum Importieren in eine andere .pyDatei?

Bearbeiten.

Die Datei Constants.pylautet:

#!/usr/bin/env python
# encoding: utf-8
"""
Constants.py
"""

MY_CONSTANT_ONE = 50
MY_CONSTANT_TWO = 51

Und myExample.pyliest:

#!/usr/bin/env python
# encoding: utf-8
"""
myExample.py
"""

import sys
import os

import Constants

class myExample:
    def __init__(self):
        self.someValueOne = Constants.MY_CONSTANT_ONE + 1
        self.someValueTwo = Constants.MY_CONSTANT_TWO + 1

if __name__ == '__main__':
    x = MyClass()

Bearbeiten.

Vom Compiler,

NameError: "Der globale Name 'MY_CONSTANT_ONE' ist nicht definiert."

Funktion init in myExample in Zeile 13 self.someValueOne = Constants.MY_CONSTANT_ONE + 1 Ausgabe kopieren Programm mit Code # 1 nach 0,06 Sekunden beendet.

SK9
quelle
2
Nein, es gibt keinen Präprozessor. Und nein, Sie werden nicht weit kommen, wenn Sie versuchen, C in Python zu codieren oder sogar Parallelen zu finden.
Das ist nicht der vollständige Traceback. Wie läuft es? python myExample.pysollte einen Traceback für Fehler geben, der Dateinamen enthält und <module>als oberste Ebene. Außerdem MY_CONSTANT_ONE sind Referenzen nicht als globaler Name - wirklich seltsam. Überprüfen Sie dreimal, ob dies wirklich die Dateien sind, die Sie ausführen (und konvertieren Sie sie möglicherweise in ASCII und entfernen Sie das # encoding: utf8Bit).
@All: Danke, mir scheint es jetzt gut zu gehen - ich weiß noch nicht warum, aber egal :).
SK9

Antworten:

129

Python ist nicht vorverarbeitet. Sie können einfach eine Datei erstellen myconstants.py:

MY_CONSTANT = 50

Und das Importieren funktioniert einfach:

import myconstants
print myconstants.MY_CONSTANT * 2
Thomas K.
quelle
@ SK9: Nun, zeigen Sie den genauen Code, den Sie ausführen (sowohl das Definieren als auch das Verwenden des Moduls).
@ Thomas: Siehe oben. Ich habe definitiv etwas Dummes verpasst, als ich die Grundlagen lernte.
SK9
@ SK9: Der von Ihnen gepostete Code enthält keinen solchen Fehler. Ich habe es mehrmals überprüft und selbst ausgeführt, es funktioniert einwandfrei. Es kann nicht einmal zu diesem Fehler führen (es gibt keinen Verweis auf einen Namen MAX_FIVE_FLUSH_KEY_INT). Poste den Traceback.
@ Thomas: Danke, dass du das getestet hast. Hmm, ich werde es noch einmal versuchen. (Die angedeutete Referenz ist ein Tippfehler.) Sie haben die Dateien buchstäblich so ausprobiert, wie sie sind? (Ich habe den gesamten Inhalt oben kopiert und eingefügt.)
SK9
@ SK9: Ich bin nicht Thomas;) Und ja, ich habe alles kopiert und eingefügt, ich habe sogar die Dateinamen so belassen, wie sie sind. Auch hier würde uns das Traceback beim Debuggen helfen.
18

Python hat weder einen Präprozessor noch Konstanten in dem Sinne, dass sie nicht geändert werden können - Sie können sie jederzeit ändern (fast können Sie konstante Objekteigenschaften emulieren, dies jedoch aus Gründen der Konstanz selten tun getan und nicht als nützlich angesehen) alles. Wenn wir eine Konstante definieren, definieren wir einen Namen, der mit Unterstrichen in Großbuchstaben geschrieben ist, und nennen ihn einen Tag - "Wir stimmen hier allen Erwachsenen zu", kein vernünftiger Mann würde eine Konstante ändern. Es sei denn natürlich, er hat sehr gute Gründe und weiß genau, was er tut. In diesem Fall können (und sollten) Sie ihn auf keinen Fall aufhalten.

Natürlich können Sie einen Namen auf Modulebene mit einem Wert definieren und in einem anderen Modul verwenden. Dies ist nicht spezifisch für Konstanten oder irgendetwas, lesen Sie auf dem Modulsystem nach.

# a.py
MY_CONSTANT = ...

# b.py
import a
print a.MY_CONSTANT

quelle
11

Und natürlich können Sie Folgendes tun:

# a.py
MY_CONSTANT = ...

# b.py
from a import *
print MY_CONSTANT
Tony
quelle
3
Von import * wird im Allgemeinen abgeraten, aber Manifestkonstanten im C-Stil, die in einer Codebasis häufig verwendet werden, sind einer der Orte, an denen es nicht verrückt ist, sie zu verwenden. Wenn Sie sie in ALL_CAPS oder mit einer Präfixkonvention benennen, die die Möglichkeit einer Kollision mit anderen Symbolen verringert, wird der Haupteinwand gegen die Redewendung beseitigt. Wenn eine Kollision auftritt, können Sie jederzeit auf den herkömmlichen Import + expliziten Namensstil zurückgreifen (import a; a .MY_CONSTNAT), im Gegensatz zu C.
Russell Borogove
auch a.MY_CONSTNAT etwas langsamer, das liegt daran, dass der Interpreter in einem Namespace nach dem Namen 'a' und dann im zweiten nach dem Namen 'MY_CONSTNAT' sucht
Tony
7

Natürlich können Sie Ihre Konstanten in ein separates Modul einfügen. Beispielsweise:

const.py:

A = 12
B = 'abc'
C = 1.2

main.py:

import const

print const.A, const.B, const.C

Beachten Sie, dass, wie oben deklariert A, Bund CVariablen sind, dh zur Laufzeit geändert werden können.

NPE
quelle
5

Versuchen Sie, Konstanten mit einem "Einstellungs" -Modul zu erstellen? und Kann ich verhindern, dass ein Objekt in Python geändert wird?

Ein weiterer nützlicher Link: http://code.activestate.com/recipes/65207-constants-in-python/ informiert uns über die folgende Option:

from copy import deepcopy

class const(object):

    def __setattr__(self, name, value):
        if self.__dict__.has_key(name):
            print 'NO WAY this is a const' # put here anything you want(throw exc and etc)
            return deepcopy(self.__dict__[name])
        self.__dict__[name] = value

    def __getattr__(self, name, value):
        if self.__dict__.has_key(name):
            return deepcopy(self.__dict__[name])

    def __delattr__(self, item):
        if self.__dict__.has_key(item):
            print 'NOOOOO' # throw exception if needed

CONST = const()
CONST.Constant1 = 111
CONST.Constant1 = 12
print a.Constant1 # 111
CONST.Constant2 = 'tst'
CONST.Constant2 = 'tst1'
print a.Constant2 # 'tst'

Sie können also eine Klasse wie diese erstellen und sie dann aus Ihrem contants.py-Modul importieren. Auf diese Weise können Sie sicher sein, dass der Wert nicht geändert oder gelöscht wird.

Artsiom Rudzenka
quelle
Danke dafür. Bevor ich nach SO gefragt habe, habe ich beide gesucht und gefunden. :)
SK9
@ SK9 oh, Entschuldigung für das Duplikat dann
Artsiom Rudzenka
4

Schauen Sie sich alternativ zur Verwendung des in mehreren Antworten beschriebenen Importansatzes das configparser- Modul an.

Die ConfigParser-Klasse implementiert eine grundlegende Parser-Sprache für Konfigurationsdateien, die eine ähnliche Struktur bietet wie Microsoft Windows INI-Dateien. Sie können dies verwenden, um Python-Programme zu schreiben, die von Endbenutzern einfach angepasst werden können.

Fredrik Pihl
quelle
2

Wenn Sie wirklich Konstanten wollen, nicht nur Variablen, die wie Konstanten aussehen, verwenden Sie standardmäßig unveränderliche Wörterbücher. Leider ist es noch nicht eingebaut, so dass Sie Rezepte von Drittanbietern (wie dieses oder jenes ) verwenden müssen.

vartec
quelle
1

Erstellen Sie eine konstante Datei mit einem beliebigen Namen wie my_constants.py. Deklarieren Sie eine solche Konstante

CONSTANT_NAME = "SOME VALUE"

Für den Zugriff auf eine Konstante in Ihrer Code-Importdatei

import my_constants as constant

und greifen Sie auf den konstanten Wert zu als -

constant.CONSTANT_NAME
Rajanbhadauria
quelle