J'écris un programme en python qui contient beaucoup de variables constantes. Je voudrais créer un fichier qui contiendra toutes ces variables comme le fichier .h en C qui contient beaucoup de #define. J'ai essayé d'utiliser configparser mais je ne l'ai pas trouvé facile et amusant à utiliser.
Connaissez-vous un meilleur moyen?
Python n'autorise pas la déclaration de constantes comme en C ou C++.
Normalement, en Python, les constantes sont en majuscules ( PEP 8 standards), ce qui aide le programmeur à savoir qu’il s’agit d’une constante.
Ex. MY_CONSTANT = "Whatever"
Une autre façon valable de le faire, que je n'utilise pas mais dont j'ai entendu parler, utilise une méthode:
def MY_CONSTANT():
return "Whatever"
En théorie, appeler MY_CONSTANT()
se comporte comme une constante.
MODIFIER
Comme le dit le commentaire, quelqu'un peut modifier la valeur en appelant
MY_CONSTANT = lambda: 'Something else'
mais n'oubliez pas que la même personne peut appeler MY_CONSTANT = "Something else"
dans le premier exemple et modifier la valeur initiale. Dans les deux cas, c'est peu probable mais possible.
Il n'y a pas de constantes en Python, comme elles existent en C ou en Java. Vous pouvez les imiter par fonctions:
def FOO():
return "foo"
Vous pouvez envelopper l'appel de fonction dans une propriété et lui donner ainsi l'apparence d'une variable:
class Const:
@property
def FOO(self):
return "foo"
CONST = Const() # You need an instance
if something == CONST.FOO:
...
Avec un peu de méta-choses, on peut obtenir des attributs non définissables avec une syntaxe concise:
def const(cls):
# Replace a class's attributes with properties,
# and itself with an instance of its doppelganger.
is_special = lambda name: (name.startswith("__") and name.endswith("__"))
class_contents = {n: getattr(cls, n) for n in vars(cls) if not is_special(n)}
def unbind(value): # Get the value out of the lexical closure.
return lambda self: value
propertified_contents = {name: property(unbind(value))
for (name, value) in class_contents.items()}
receptor = type(cls.__name__, (object,), propertified_contents)
return receptor() # Replace with an instance, so properties work.
@const
class Paths(object):
home = "/home"
null = "/dev/null"
Vous pouvez maintenant accéder à Paths.home
en tant que valeur normale, mais vous ne pouvez pas l'affecter. Vous pouvez définir plusieurs classes décorées avec @const
, tout comme plusieurs fichiers .h
.
Vous pouvez utiliser quelque chose comme ceci:
Structure des fichiers:
myapp/
__init__.py
settings.py
main.py
settings.py
CONST_A = 'A'
CONST_B = 'B'
__init__.py
from . import settings as global_settings
class Settings:
def __init__(self):
for setting in dir(global_settings):
if setting.isupper():
setattr(self, setting, getattr(global_settings, setting))
def __setattr__(self, attr, value):
if not getattr(self, attr, None):
super().__setattr__(attr, value)
else:
raise TypeError("'constant' does not support item assignment")
settings = Settings()
main.py
import settings
print(settings.CONST_A) # prints A
settings.CONST_A = 'C' # raises TypeError error
print(settings.CONST_A) # prints A
settings.CONST_C = 'C' # also able to add new constants
print(settings.CONST_C) # prints C
__Setattr__ dans la classe Settings écrasée rend tous les attributs en lecture seule . La seule condition requise est que toutes les constantes soient dans votre settings.py écrit en lettres majuscules . Attention, que ça ne marchera pas si vous importez directement des variables:
from settings import CONST_A
print(settings.CONST_A) # prints A
settings.CONST_A = 'C' # sets C
print(settings.CONST_A) # prints C
Python n'est pas prétraité. Vous pouvez simplement créer un fichier constant.py
#!/usr/bin/env python
# encoding: utf-8
"""
constant.py
"""
MY_CONSTANT = 50
Importez le fichier constant.py à chaque fois que vous souhaitez des valeurs constantes comme ci-dessous.
#!/usr/bin/env python
# encoding: utf-8
"""
example.py
"""
import constant
print constant.MY_CONSTANT * 2
De cette façon, vous pouvez utiliser des constantes sur l'ensemble du projet.
Vous avez également la possibilité, si les constantes sont liées à une classe particulière et utilisées en privé dans cette classe de les rendre spécifiques à cette classe:
class Foo(object):
GOOD = 0
BAD = 1
def __init__(self...
Si vous voulez définir et utiliser tout le module, placez-les au-dessus du module
PIE = 3.47
class Foo(object):
def __init__(self...