Importar una larga lista de constantes a un archivo de Python

90

En Python, ¿existe un análogo de la Cdeclaración del preprocesador como ?:

#define MY_CONSTANT 50

Además, tengo una gran lista de constantes que me gustaría importar a varias clases. ¿Existe un análogo de declarar las constantes como una secuencia larga de declaraciones como la anterior en un .pyarchivo e importarlas a otro .pyarchivo?

Editar.

El archivo Constants.pydice:

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

MY_CONSTANT_ONE = 50
MY_CONSTANT_TWO = 51

Y myExample.pylee:

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

Editar.

Desde el compilador,

NameError: "el nombre global 'MY_CONSTANT_ONE' no está definido"

función init en myExample en la línea 13 self.someValueOne = Constants.MY_CONSTANT_ONE + 1 copia de salida El programa salió con el código # 1 después de 0.06 segundos.

SK9
fuente
2
No, no hay preprocesador. Y no, no llegará muy lejos tratando de codificar C en Python, o incluso tratando de encontrar paralelos.
Ese no es el rastreo completo. ¿Cómo lo estás ejecutando? python myExample.pydebe dar un seguimiento del error que incluya nombres de archivos y <module>como nivel superior. Además, MY_CONSTANT_ONE no son referencias como nombre global, realmente extraño. Verifique tres veces que esos son realmente los archivos que está ejecutando (y quizás conviértalos a ASCII y elimine el # encoding: utf8bit).
@Todos: Gracias, parece que estoy bien ahora, todavía no estoy seguro de por qué, pero no importa :).
SK9

Respuestas:

132

Python no está preprocesado. Simplemente puede crear un archivo myconstants.py:

MY_CONSTANT = 50

E importarlos simplemente funcionará:

import myconstants
print myconstants.MY_CONSTANT * 2
Thomas K
fuente
@ SK9: Bueno, muestre el código exacto que está ejecutando (tanto definiendo como usando el módulo).
@Thomas: Ver arriba. Definitivamente me he perdido algo tonto en algún lugar mientras estoy aprendiendo lo básico.
SK9
@ SK9: No hay tal error en el código que publicó. Lo revisé varias veces y lo ejecuté yo mismo, funciona bien. Que no puede incluso dar lugar a este error (no hay referencia a un nombre MAX_FIVE_FLUSH_KEY_INT). Publique el rastreo.
@Thomas: Gracias por probar esto. Hmm, lo intentaré de nuevo. (La referencia a la que se alude es un error tipográfico). ¿Probó los archivos literalmente como están? (Copié y pegué el contenido completo de arriba.)
SK9
@ SK9: No soy Thomas;) Y sí, copié y pegué todo, incluso dejé los nombres de archivo como están. Una vez más, el rastreo nos ayudaría a depurar.
18

Python no tiene un preprocesador, ni tiene constantes en el sentido de que no se pueden cambiar; siempre puede cambiar (casi, puede emular las propiedades de los objetos constantes, pero hacer esto por el bien de la constancia rara vez es hecho y no considerado útil) todo. Al definir una constante, definimos un nombre que está en mayúsculas con guiones bajos y lo llamamos un día: "Aquí todos somos adultos que consienten", ningún hombre en su sano juicio cambiaría una constante. A menos que, por supuesto, tenga muy buenas razones y sepa exactamente lo que está haciendo, en cuyo caso no puedes (y probablemente no deberías) detenerlo de cualquier manera.

Pero, por supuesto, puede definir un nombre de nivel de módulo con un valor y usarlo en otro módulo. Esto no es específico de las constantes ni nada, lea sobre el sistema del módulo.

# a.py
MY_CONSTANT = ...

# b.py
import a
print a.MY_CONSTANT

fuente
11

Y por supuesto puedes hacer:

# a.py
MY_CONSTANT = ...

# b.py
from a import *
print MY_CONSTANT
Tony
fuente
3
En general, se desaconseja la importación *, pero las constantes de manifiesto de estilo C que se usan ampliamente en una base de código son uno de los lugares donde no es una locura usarlo. Nombrarlos en ALL_CAPS o con alguna convención de prefijo que reduzca la posibilidad de colisión con otros símbolos elimina la principal objeción al idioma, y ​​si ocurre una colisión, siempre puede recurrir al estilo convencional de importación + nombre explícito (import a; a .MY_CONSTNAT), a diferencia de C.
Russell Borogove
también a.MY_CONSTNAT un poco más lento, eso es porque el intérprete busca en un espacio de nombres el nombre 'a' y luego en el segundo nombre de enemigo 'MY_CONSTNAT'
tony
7

Claro, puede poner sus constantes en un módulo separado. Por ejemplo:

const.py:

A = 12
B = 'abc'
C = 1.2

main.py:

import const

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

Tenga en cuenta que según lo declarado anteriormente, A, By Cson variables, es decir, se pueden cambiar en tiempo de ejecución.

NPE
fuente
5

Trate de buscar ¿ Crear constantes usando un módulo de "configuración"? y ¿Puedo evitar modificar un objeto en Python?

Otro enlace útil: http://code.activestate.com/recipes/65207-constants-in-python/ nos informa sobre la siguiente opción:

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'

Entonces podría crear una clase como esta y luego importarla desde su módulo contants.py. Esto le permitirá estar seguro de que el valor no se modificará ni se eliminará.

Artsiom Rudzenka
fuente
Gracias por esto. Antes de preguntar por SO, busqué y encontré ambos. :)
SK9
@ SK9 oh, perdón por duplicar entonces
Artsiom Rudzenka
4

Como alternativa al uso del enfoque de importación descrito en varias respuestas, eche un vistazo al módulo configparser .

La clase ConfigParser implementa un lenguaje de análisis de archivos de configuración básico que proporciona una estructura similar a la que encontraría en los archivos INI de Microsoft Windows. Puede usar esto para escribir programas Python que los usuarios finales pueden personalizar fácilmente.

Fredrik Pihl
fuente
2

Si realmente desea constantes, no solo variables que parezcan constantes, la forma estándar de hacerlo es utilizar diccionarios inmutables. Desafortunadamente, aún no está integrado, por lo que debe usar recetas de terceros (como esta o aquella ).

vartec
fuente
2

crear un archivo constante con cualquier nombre como my_constants.py declarar constante así

CONSTANT_NAME = "SOME VALUE"

Para acceder a la constante en su archivo de importación de código como ese

import my_constants as constant

y acceda al valor constante como -

constant.CONSTANT_NAME
rajanbhadauria
fuente