Импорт длинного списка констант в файл Python

90

В Python есть аналог Cинструкции препроцессора, например ?:

#define MY_CONSTANT 50

Кроме того, у меня есть большой список констант, которые я хотел бы импортировать в несколько классов. Есть ли аналог объявления констант как длинной последовательности операторов, подобных приведенной выше, в .pyфайле и их импорта в другой .pyфайл?

Редактировать.

Файл Constants.pyгласит:

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

MY_CONSTANT_ONE = 50
MY_CONSTANT_TWO = 51

И myExample.pyчитает:

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

Редактировать.

Из компилятора

NameError: «глобальное имя MY_CONSTANT_ONE не определено»

функция init в myExample в строке 13 self.someValueOne = Constants.MY_CONSTANT_ONE + 1 вывод копии Программа завершилась с кодом # 1 через 0,06 секунды.

SK9
источник
2
Нет, препроцессора нет. И нет, вы далеко не уйдете, пытаясь написать код C на Python или даже пытаясь найти параллели.
Это не полная трассировка. Как ты им управляешь? python myExample.pyдолжен дать обратную связь при ошибке, которая включает имена файлов и <module>как верхний уровень. К тому MY_CONSTANT_ONE же ссылки не являются глобальным именем - это действительно странно. Трижды проверьте, действительно ли это те файлы, которые вы используете (и, возможно, преобразуйте их в ASCII и удалите # encoding: utf8бит).
@All: Спасибо, мне кажется, сейчас все в порядке - пока не знаю почему, но неважно :).
SK9

Ответы:

132

Python не подвергается предварительной обработке. Вы можете просто создать файл myconstants.py:

MY_CONSTANT = 50

И их импорт будет работать:

import myconstants
print myconstants.MY_CONSTANT * 2
Томас К
источник
@ SK9: Хорошо, покажите точный код, который вы используете (как определение, так и использование модуля).
@ Томас: См. Выше. Я определенно пропустил что-то глупое, когда изучаю основы.
SK9
@ SK9: В опубликованном вами коде такой ошибки нет. Проверял несколько раз и сам запускал, работает нормально. Это даже не может привести к этой ошибке (нет ссылки на имя MAX_FIVE_FLUSH_KEY_INT). Опубликуйте трассировку.
@Thomas: Спасибо за тестирование. Хм, попробую еще раз. (Упомянутая ссылка является опечаткой.) Вы пробовали файлы буквально как есть? (Я скопировал и вставил все содержимое выше.)
SK9,
@ SK9: Я не Томас;) И да, я все скопировал и вставил, даже имена файлов оставил как есть. Опять же, трассировка поможет нам отладить.
18

Python не имеет препроцессора и констант в том смысле, что их нельзя изменить - вы всегда можете изменить (почти, вы можете имитировать свойства константных объектов, но делать это ради постоянства редко) сделано и не считается полезным) все. При определении константы мы определяем имя в верхнем регистре с подчеркиванием и называем его днем: «Мы все здесь взрослые по согласию», ни один здравомыслящий человек не изменит константу. Если, конечно, у него нет веских причин и он точно не знает, что делает, и в этом случае вы не можете (и, вероятно, не должны) останавливать его в любом случае.

Но, конечно, вы можете определить имя уровня модуля со значением и использовать его в другом модуле. Это не относится к константам или чему-то еще, читайте в модульной системе.

# a.py
MY_CONSTANT = ...

# b.py
import a
print a.MY_CONSTANT

источник
11

И, конечно же, вы можете:

# a.py
MY_CONSTANT = ...

# b.py
from a import *
print MY_CONSTANT
Тони
источник
3
import * не рекомендуется в целом, но константы манифеста в стиле C, которые широко используются в кодовой базе, являются одним из тех мест, где его использование небезумно. Именование их в ALL_CAPS или с каким-либо префиксным соглашением, которое снижает вероятность столкновения с другими символами, устраняет основное возражение против идиомы, и если конфликт все же происходит, вы всегда можете вернуться к обычному стилю импорта + явного имени (import a; a .MY_CONSTNAT), в отличие от C.
Рассел Борогов
также a.MY_CONSTNAT немного медленнее, потому что интерпретатор ищет в одном пространстве имен имя 'a', а затем во втором имя врага 'MY_CONSTNAT'
Тони
7

Конечно, вы можете поместить свои константы в отдельный модуль. Например:

const.py:

A = 12
B = 'abc'
C = 1.2

main.py:

import const

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

Следует отметить , что , как заявлено выше, A, Bи Cявляются переменными, т.е. может быть изменен во время выполнения.

NPE
источник
5

Попробуй посмотреть Создание констант с помощью модуля "настройки"? и Могу ли я предотвратить изменение объекта в Python?

Еще одна полезная ссылка: http://code.activestate.com/recipes/65207-constants-in-python/ рассказывает нам о следующем варианте:

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'

Таким образом, вы можете создать такой класс, а затем импортировать его из модуля contants.py. Это позволит быть уверенным, что значение не будет изменено, удалено.

Артем Рудзенко
источник
Спасибо за это. Прежде чем спросить о SO, я искал и нашел их обоих. :)
SK9
@ SK9 ой, тогда извините за дубликат
Артем Рудзенко
4

В качестве альтернативы использованию подхода импорта, описанного в нескольких ответах, посмотрите модуль configparser .

Класс ConfigParser реализует базовый язык парсера файлов конфигурации, который обеспечивает структуру, аналогичную той, что вы найдете в файлах INI Microsoft Windows. Вы можете использовать это для написания программ Python, которые могут быть легко настроены конечными пользователями.

Фредрик Пиль
источник
2

Если вам действительно нужны константы, а не просто переменные, похожие на константы, стандартный способ сделать это - использовать неизменяемые словари. К сожалению, он еще не встроен, поэтому вам придется использовать сторонние рецепты (например, тот или другой ).

Vartec
источник
2

создать постоянный файл с любым именем, например my_constants.py, объявить такую ​​константу

CONSTANT_NAME = "SOME VALUE"

Для доступа к константе в вашем файле импорта кода, подобном этому

import my_constants as constant

и получить доступ к постоянному значению как -

constant.CONSTANT_NAME
раджанбхадаурия
источник