Importar uma longa lista de constantes para um arquivo Python

90

Em Python, existe um análogo da Cinstrução do pré - processador, como ?:

#define MY_CONSTANT 50

Além disso, tenho uma grande lista de constantes que gostaria de importar para várias classes. Existe um análogo de declarar as constantes como uma longa sequência de instruções como o acima em um .pyarquivo e importá-lo para outro .pyarquivo?

Editar.

O arquivo Constants.pydiz:

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

MY_CONSTANT_ONE = 50
MY_CONSTANT_TWO = 51

E myExample.pylê:

#!/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.

Do compilador,

NameError: "nome global 'MY_CONSTANT_ONE' não está definido"

função init em myExample na linha 13 self.someValueOne = Constants.MY_CONSTANT_ONE + 1 saída de cópia O programa saiu com o código # 1 após 0,06 segundos.

SK9
fonte
2
Não, não há pré-processador. E não, você não irá muito longe tentando codificar C em Python, ou mesmo tentando encontrar paralelos.
Esse não é o rastreamento completo. Como você está administrando isso? python myExample.pydeve fornecer um rastreamento do erro que inclui nomes de arquivo e <module>como nível superior. Além disso, MY_CONSTANT_ONE não são referências como um nome global - realmente estranho. Verifique três vezes se esses são realmente os arquivos que você está executando (e talvez converta-os para ASCII e remova o # encoding: utf8bit).
@Todos: Obrigado, parece que estou bem agora - ainda não sei por que, mas deixa para lá :).
SK9

Respostas:

131

Python não é pré-processado. Você pode apenas criar um arquivo myconstants.py:

MY_CONSTANT = 50

E importá-los simplesmente funcionará:

import myconstants
print myconstants.MY_CONSTANT * 2
Thomas K
fonte
@ SK9: Bem, mostre o código exato que você está executando (definindo e usando o módulo).
@Thomas: Veja acima. Eu definitivamente perdi algo idiota em algum lugar enquanto estou aprendendo o básico.
SK9 de
@ SK9: Esse erro não existe no código que você postou. Eu verifiquei várias vezes e executei sozinho, ele funciona muito bem. Ele não pode mesmo levar a este erro (não há nenhuma referência a um nome MAX_FIVE_FLUSH_KEY_INT). Publique o traceback.
@Thomas: Obrigado por testar isso. Hmm, vou tentar novamente. (A referência mencionada é um erro de digitação.) Você tentou os arquivos literalmente como estão? (Copiei e colei todo o conteúdo acima.)
SK9
@ SK9: Não sou o Thomas;) E sim, copiei e colei tudo, até deixei os nomes dos arquivos como estão. Novamente, o traceback nos ajudaria a depurar.
18

Python não tem um pré-processador, nem tem constantes no sentido de que não podem ser alteradas - você sempre pode alterar (quase, você pode emular propriedades de objeto constante, mas fazer isso por uma questão de constante-ness raramente é feito e não considerado útil) tudo. Ao definir uma constante, definimos um nome que é maiúsculo com sublinhados e encerramos o dia - "Somos todos adultos conscientes aqui", nenhum homem são mudaria uma constante. A menos, é claro, que ele tenha boas razões e saiba exatamente o que está fazendo; nesse caso, você não pode (e provavelmente não deveria) impedi-lo de qualquer maneira.

Mas é claro que você pode definir um nome de nível de módulo com um valor e usá-lo em outro módulo. Isso não é específico para constantes ou qualquer coisa, leia no sistema de módulos.

# a.py
MY_CONSTANT = ...

# b.py
import a
print a.MY_CONSTANT

fonte
11

E é claro que você pode fazer:

# a.py
MY_CONSTANT = ...

# b.py
from a import *
print MY_CONSTANT
Tony
fonte
3
import * é desencorajado em geral, mas constantes de manifesto de estilo C que são amplamente usadas em uma base de código são um dos lugares onde não é insano usá-lo. Nomeando-os em ALL_CAPS ou com alguma convenção de prefixo que reduza a possibilidade de colisão com outros símbolos remove a principal objeção ao idioma, e se ocorrer uma colisão, você sempre pode voltar para o estilo de nome explícito + importação convencional (import a; a .MY_CONSTNAT), ao contrário de C.
Russell Borogove
também a.MY_CONSTNAT um pouco mais lento, isso porque o intérprete procura em um namespace o nome 'a' e, em seguida, no segundo, o nome inimigo 'MY_CONSTNAT'
Tony
7

Claro, você pode colocar suas constantes em um módulo separado. Por exemplo:

const.py:

A = 12
B = 'abc'
C = 1.2

main.py:

import const

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

Note-se que, tal como declarado acima, A, Be Csão variáveis, ou seja, pode ser alterado em tempo de execução.

NPE
fonte
5

Tente olhar Criar constantes usando um módulo "configurações"? e posso evitar a modificação de um objeto em Python?

Outro link útil: http://code.activestate.com/recipes/65207-constants-in-python/ nos informa sobre a seguinte opção:

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'

Portanto, você pode criar uma classe como essa e, em seguida, importá-la do módulo contants.py. Isso permitirá que você tenha certeza de que o valor não será alterado ou excluído.

Artsiom Rudzenka
fonte
Obrigado por isso. Antes de perguntar no SO, pesquisei e encontrei ambos. :)
SK9
@ SK9 oh, desculpe pela duplicata então
Artsiom Rudzenka
4

Como alternativa ao uso da abordagem de importação descrita em várias respostas, dê uma olhada no módulo configparser .

A classe ConfigParser implementa uma linguagem de análise de arquivo de configuração básica que fornece uma estrutura semelhante à que você encontraria em arquivos INI do Microsoft Windows. Você pode usar isso para escrever programas Python que podem ser personalizados pelos usuários finais facilmente.

Fredrik Pihl
fonte
2

Se você realmente deseja constantes, não apenas variáveis ​​parecidas com constantes, a maneira padrão de fazer isso é usar dicionários imutáveis. Infelizmente ainda não está embutido, então você tem que usar receitas de terceiros (como esta ou aquela ).

Vartec
fonte
2

cria um arquivo constante com qualquer nome como my_constants.py declara uma constante assim

CONSTANT_NAME = "SOME VALUE"

Para acessar constantes em seu arquivo de importação de código como esse

import my_constants as constant

e acessar o valor constante como -

constant.CONSTANT_NAME
rajanbhadauria
fonte