Importazione di un lungo elenco di costanti in un file Python


92

In Python, esiste un analogo Cdell'istruzione del preprocessore come ?:

#define MY_CONSTANT 50

Inoltre, ho un ampio elenco di costanti che vorrei importare in diverse classi. Esiste un analogo della dichiarazione delle costanti come una lunga sequenza di istruzioni come quella sopra in un .pyfile e dell'importazione in un altro .pyfile?

Modificare.

Il file Constants.pylegge:

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

MY_CONSTANT_ONE = 50
MY_CONSTANT_TWO = 51

E myExample.pylegge:

#!/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()

Modificare.

Dal compilatore,

NameError: "il nome globale" MY_CONSTANT_ONE "non è definito"

function init in myExample alla riga 13 self.someValueOne = Constants.MY_CONSTANT_ONE + 1 copia output Programma terminato con codice # 1 dopo 0,06 secondi.


2
No, non esiste un preprocessore. E no, non andrai molto lontano cercando di codificare C in Python, o nemmeno cercando di trovare paralleli.

Non è tutto il traceback. Come lo stai facendo? python myExample.pydovrebbe fornire un traceback in caso di errore che include i nomi dei file e <module>come livello superiore. Inoltre, MY_CONSTANT_ONE non sono riferimenti come nome globale - davvero strano. Controlla tre volte che quelli siano davvero i file che stai eseguendo (e forse convertili in ASCII e rimuovi il # encoding: utf8bit).

@ Tutti: Grazie, mi sembra di stare bene ora - non sono ancora sicuro del perché, ma non importa :).
SK9

Risposte:


139

Python non è preelaborato. Puoi semplicemente creare un file myconstants.py:

MY_CONSTANT = 50

E importarli funzionerà:

import myconstants
print myconstants.MY_CONSTANT * 2

@ SK9: Bene, mostra il codice esatto che stai eseguendo (sia definendo che usando il modulo).

@Thomas: vedi sopra. Ho sicuramente perso qualcosa di stupido da qualche parte mentre sto imparando le basi.
SK9

@ SK9: non ci sono errori di questo tipo nel codice che hai pubblicato. L'ho controllato più volte e l'ho eseguito io stesso, funziona perfettamente. Non può nemmeno portare a questo errore (non c'è alcun riferimento a un nome MAX_FIVE_FLUSH_KEY_INT). Pubblica il traceback.

@ Thomas: grazie per averlo provato. Hmm, proverò di nuovo. (Il riferimento a cui si allude è un errore di battitura.) Hai provato i file letteralmente come sono? (Ho copiato e incollato l'intero contenuto sopra.)
SK9

@ SK9: non sono Thomas;) E sì, ho copiato e incollato tutto, ho persino lasciato i nomi dei file così come sono. Ancora una volta, il traceback ci aiuterebbe a eseguire il debug.

18

Python non ha un preprocessore, né ha costanti nel senso che non possono essere modificate: puoi sempre cambiare (quasi, puoi emulare proprietà costanti dell'oggetto, ma farlo per amore della costanza è raramente fatto e non ritenuto utile) tutto. Quando definiamo una costante, definiamo un nome che è maiuscolo con trattini bassi e lo chiamiamo giorno: "Siamo tutti adulti consenzienti qui", nessun uomo sano di mente cambierebbe una costante. A meno che ovviamente non abbia ottime ragioni e sappia esattamente cosa sta facendo, nel qual caso non puoi (e probabilmente non dovresti) fermarlo in entrambi i casi.

Ma ovviamente puoi definire un nome a livello di modulo con un valore e usarlo in un altro modulo. Questo non è specifico per le costanti o altro, leggi sul sistema del modulo.

# a.py
MY_CONSTANT = ...

# b.py
import a
print a.MY_CONSTANT

11

E naturalmente puoi fare:

# a.py
MY_CONSTANT = ...

# b.py
from a import *
print MY_CONSTANT


3
import * è sconsigliato in generale, ma le costanti manifest in stile C ampiamente utilizzate in una base di codice sono uno dei posti in cui non è folle usarlo. Denominandoli in ALL_CAPS o con qualche convenzione di prefisso che riduce la possibilità di collisione con altri simboli rimuove l'obiezione principale all'idioma, e se si verifica una collisione puoi sempre tornare allo stile di importazione convenzionale + nome esplicito (import a; .MY_CONSTNAT), a differenza di C.
Russell Borogove

anche a.MY_CONSTNAT un po 'più lento, perché l'interprete cerca in uno spazio dei nomi il nome "a" e poi nel secondo il nome del nemico "MY_CONSTNAT"
tony

7

Certo, puoi mettere le tue costanti in un modulo separato. Per esempio:

const.py:

A = 12
B = 'abc'
C = 1.2

main.py:

import const

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

Si noti che, come dichiarato in precedenza, A, Be Csono variabili, cioè possono essere modificate in fase di esecuzione.


5

Prova a cercare creare costanti utilizzando un modulo "impostazioni"? e posso impedire la modifica di un oggetto in Python?

Un altro collegamento utile: http://code.activestate.com/recipes/65207-constants-in-python/ ci parla della seguente opzione:

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'

Quindi potresti creare una classe come questa e poi importarla dal tuo modulo contants.py. Ciò ti consentirà di essere sicuro che il valore non verrà modificato, eliminato.


Grazie per questo. Prima di chiedere a SO ho cercato e trovato entrambi. :)
SK9

@ SK9 oh, scusa per il duplicato allora
Artsiom Rudzenka

4

In alternativa all'utilizzo dell'approccio di importazione descritto in diverse risposte, dai un'occhiata al modulo configparser .

La classe ConfigParser implementa un linguaggio parser di file di configurazione di base che fornisce una struttura simile a quella che si trova nei file INI di Microsoft Windows. Puoi usarlo per scrivere programmi Python che possono essere personalizzati facilmente dagli utenti finali.


2

Se vuoi davvero le costanti, non solo le variabili che sembrano costanti, il modo standard per farlo è usare dizionari immutabili. Sfortunatamente non è ancora integrato, quindi devi usare ricette di terze parti (come questa o quella ).


2

crea un file costante con qualsiasi nome come my_constants.py dichiara costante in questo modo

CONSTANT_NAME = "SOME VALUE"

Per accedere alla costante nel tuo file di importazione del codice in questo modo

import my_constants as constant

e accedi al valore costante come -

constant.CONSTANT_NAME
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.