web-dev-qa-db-fra.com

quelle est la meilleure façon de définir les variables constantes python 3

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? 

4
TomE8

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.

10
scharette

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.

3
9000

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
1
Artem Nepo

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...
0
Ankireddy