Константы в Python: в корне модуля или в пространстве имен внутри модуля?
Я строю модуль Python со ста константами.
Я бы хотел избежать проблем с именами, когда люди импортировали мой модуль, поэтому мне было интересно, что будет лучшим способом сделать это.
MY_CONSTANT = 1
MY_SECOND_CONSTANT = 2
...
MY2_CONSTANT = "a"
MY2_SECOND_CONSTANT = "b"
...
или
class My:
CONSTANT = 1
SECOND_CONSTANT = 2
...
class My2
CONSTANT = "a"
SECOND_CONSTANT = "b"
...
Или, может быть, еще одно из ваших предложений?
Из Java, я, конечно, предпочитаю второй способ, но некоторые могут найти его излишним...
Ответы
Ответ 1
Смотря как. Обычно константы определяются на уровне модуля. Но если у вас есть много констант для category_a
и category_b
, возможно, имеет смысл добавить constants
подпакета с модулями constants.category_a
и constants.category_b
.
Я бы воздержался от использования class
- его можно было бы создать, что не имеет смысла, и он не имеет никакого преимущества перед модулем, кроме того, что позволяет вам втиснуть более одного в один физический файл (чего, вероятно, не следует делать, если есть). так много постоянных). Версия Java могла бы использовать статический класс, но эквивалент Python - это модуль.
Конфликты имен не являются проблемой в Python, за исключением случаев, когда вы import *
но вы все равно не должны этого делать. Пока в модуле нет конфликтов имен, будьте уверены, что пользователь не извлечет все имена из вашего модуля в свои собственные и не импортирует их под именем, конфликтующим с другим модулем.
Ответ 2
Каждый модуль предоставляет свое собственное пространство имен, поэтому нет необходимости создавать еще один.
Наличие модуля foo.py
:
FOO = 1
BAR = 2
SHMOO = 3
вы можете использовать его следующим образом:
import foo
foo.BAR
Ответ 3
Из руководство по стилю:
Константы обычно определяются на уровне модуля и записываются во всех
заглавные буквы с подчеркиваниями, разделяющими слова. Примеры включают
MAX_OVERFLOW и TOTAL.
Ответ 4
Если вы используете классы, вы можете запретить переписывать константы (или запрещать даже добавлять константы к этому классу). Кроме того, преимущество использования класса над файлами (модулями) - это когда у вас много групп, вам не нужно иметь много файлов.
Итак, это будет выглядеть так:
class MyConstBaseClass:
"""
forbids to overwrite existing variables
forbids to add new values if "locked" variable exists
"""
def __setattr__(self,name,value):
if(self.__dict__.has_key("locked")):
raise NameError("Class is locked can not add any attributes (%s)"%name)
if self.__dict__.has_key(name):
raise NameError("Can't rebind const(%s)"%name)
self.__dict__[name]=value
class MY_CONST_GRP1(MyConstBaseClass):
def __init__(self):
self.const1 = "g1c1"
self.const2 = "g1c2"
my_const_grp1 = MY_CONST_GRP1()
class MY_CONST_GRP2(MyConstBaseClass):
def __init__(self):
self.const1 = "g2c1"
self.const3 = "g2c3"
self.locked = 1 # this will create lock for adding constants
my_const_grp2 = MY_CONST_GRP2()
print my_const_grp1.const1 # prints "g1c1"
print my_const_grp1.const2 # prints "g1c2"
print my_const_grp2.const1 # prints "g2c1"
print my_const_grp2.const3 # prints "g2c3"
my_const_grp1.new_constant = "new value" #adding constants is allowed to this group
#my_const_grp1.const1 = "new value" #redefine would raise an error
#my_const_grp2.new_constant = "first value" #adding constant is also forbidden
#my_const_grp2.const1 = "new value" #redefine would raise an error
Ниже приведен пример simillar