¿Realmente debería usar todo en mayúsculas para mis constantes?

34

Soy un programador de Python principalmente que usa pylint para el código fuente de linting. Puedo eliminar todas las advertencias excepto una: Nombre no válido para una constante. Cambiar el nombre a mayúsculas lo arregla, pero ¿realmente se supone que debo hacer eso? Si lo hago, encuentro que mi código se ve feo ya que la mayoría de las variables son constantes (según pylint).

Abhishek Kumar
fuente
2
Si la mayoría de sus variables son constantes de nivel de módulo, probablemente esté haciendo algo inusual. La mayoría de ellos deberían vivir dentro de las funciones.
RemcoGerlich
1
¿Puedes mostrarnos una muestra de tu código que pylint cree que son constantes?
Winston Ewert
@WinstonEwertNOTES_DIRECTORY = argv[1] chdir(NOTES_DIRECTORY) FILES = glob('*.txt') RAND_FILE = choice(FILES) with open(RAND_FILE) as notes_file: POINTS = notes_file.readlines() RAND_POINT = choice(POINTS)
Abhishek Kumar
@AbhishekKumar, ¿está su código en una función o en el nivel superior?
Winston Ewert
@ WinstonEwert En el nivel superior y después de seguir las instrucciones de PyLint.
Abhishek Kumar

Respuestas:

33

Probablemente esté escribiendo código como este:

notes_director = argv[1]
chdir(notes_director)
files = glob('*.txt')
rand_file = choice(files)
with open(rand_file) as notes_file: 
    points = notes_file.readlines() 
    rand_point = choice(points)

Debe mover este código a una función:

def main():
    notes_director = argv[1]
    chdir(notes_director)
    files = glob('*.txt')
    rand_file = choice(files)
    with open(rand_file) as notes_file: 
        points = notes_file.readlines() 
        rand_point = choice(points)

# actually call the main function    
main()

Pylint asume que el código que realmente hace el trabajo estará dentro de una función. Debido a que tiene este código en el nivel superior de su código en lugar de dentro de una función, se confunde.

En términos generales, es mejor trabajar dentro de una función que en el nivel superior. Esto le permite organizar mejor lo que está haciendo y facilita la reutilización. Realmente solo debe tener código que realice un algoritmo fuera de una función en un script rápido y sucio.

Winston Ewert
fuente
1
Totalmente en desacuerdo, creo que hay muchas buenas razones pitónicas para usar variables de nivel de módulo. Creo que este consejo es simplemente un artefacto de la lectura incorrecta de Pyl8 de Pylint, y suponiendo que el inverso de "las constantes deberían estar a nivel de módulo" también debería ser cierto.
MetricSystem
21

Sí. De acuerdo con la regla de PEP8 sobre constantes :

Las constantes generalmente se definen a nivel de módulo y se escriben en letras mayúsculas con guiones bajos que separan las palabras. Los ejemplos incluyen MAX_OVERFLOWy TOTAL.

Versión larga:

En la comunidad Python (como en muchas otras comunidades) existen convenciones sobre cómo escribir código. Esto es diferente del código de trabajo : incluso si escribe sus constantes en minúsculas, su código aún funciona.

Pero existe un consenso de la comunidad (como se documenta en PEP8) que se "aplica" con herramientas como pylint . Si programa para su propia felicidad, puede descuidar los consejos que le da pylint. Si desea un intercambio abierto con la comunidad, también conocido como »alguien además de mí debería usar mi código«, debe preparar su código de acuerdo con PEP8.

Thomas Junk
fuente
77
Por otro lado, es completamente posible pylintequivocarse. Python no proporciona una forma de distinguir una constante de una variable, aparte de que se espera que la constante siempre tenga el mismo valor. pylintasume que todo lo que se establece una sola vez y que nunca cambia es una constante, pero a menos que se pretenda que sea una constante, eso podría ser solo un artefacto de la implementación. Y específicamente el código dado en el comentario a la pregunta tiene valores que serán diferentes en cada ejecución, por lo tanto, no deben considerarse constantes incluso si pylint cree que lo son.
Jules
@Jules Llamaría a las variables establecidas una vez y que cambian durante el tiempo de ejecución nunca más una constante, por lo tanto, existe en muchos idiomas (por ejemplo, en JS) una constpalabra clave. Aunque el valor inicial es diferente, aparte de tal vez PI.
Thomas Junk
1
Distinguiría entre una variable inmutable (es decir, algo que se establece en tiempo de ejecución y no se modifica) y una constante (es decir, algo que es igual en cada ejecución del programa, y ​​si el lenguaje proporciona la opción de hacerlo, se podría calcular en tiempo de compilación ) ... el punto es que debido a la falta de alguna forma de especificar la distinción a python, se pylintasume esto último incluso cuando el primero es el caso.
Jules
Pylint definitivamente está equivocado, ya que dice "las constantes deben ser de nivel de módulo" y supone el inverso "el nivel de módulo debe ser de constantes". Pero debido a que es una herramienta buena y útil, parece que nos estamos quedando atrapados con ella.
MetricSystem
@MetricSystem, ¿qué función, en su opinión, tendría una variable de nivel de módulo además de ser una constante? ¿Debería ser mutable?
Thomas Junk
13

Se debe usar la norma de la comunidad PEP8 y Python ALL_CAPS_CONSTANTS. Es una pista visual común, utilizada durante décadas en C, Java, Perl, PHP, Python, bash y otros lenguajes de programación y entornos de shell. Pero en el lenguaje moderno en línea, TODAS LAS MAYÚSCULAS SIGNIFICA GRITOS . Y gritar es grosero.

Python es, sin embargo, bastante inconsistente al respecto ALL_CAPS_CONSTANTS. JavaScript puede tener Math.PI, pero Python tiene math.pi. No hay una constante más reconocible o duradera que π. O considere sys.version_info, la versión de Python que está ejecutando. 100% constante durante la vida de su programa - mucho más que PORTo MAX_ITERATIONSu otras constantes que le defina. ¿O qué tal sys.maxsize? El valor entero nativo máximo de su plataforma es constante no solo en una o dos ejecuciones de programa, sino también en la vida de su hardware.

Si estas constantes - incluyendo algunos como π y e que son constantes fundamentales del universo, y no varían a lo largo toda la eternidad - si es que puede ser minúscula, así ... lo mismo pueden hacer otras constantes. Tu puedes elegir.

Recuerde, PEP8 es una guía de estilo. Una directriz, no una ley. Una guía a menudo infringida incluso por la biblioteca estándar de Python. Y citando otra directriz central de Python, PEP20 (también conocido como "El Zen de Python"):

  • Hermoso es mejor que feo
  • La legibilidad cuenta
  • La practicidad es mejor que la pureza.

En una nota práctica, cuando el jugador de un programa YELLY_CONSTANTy SHOUTY_PARAMETERempieza a rallar, es útil recordar que las constantes en mayúsculas generalmente no son realmente soportando los ideales platónicos , pero los parámetros de la ejecución del programa. No hay nada realmente constante acerca de PORT, SITENAMEo NUMRUNS, y no tienen que ser administrados como programas globales independientes. Por ejemplo, se pueden colocar en un diccionario como un paquete de parámetros de programa accesible a nivel mundial:

config = {
    'port': 80,
    'sitename': "Bubba's Blog",
    'numruns': 100,
}

Python también tiene una palabra clave bien el traspaso de parámetros instalación que reduce la necesidad de su uso APPARENTLY_ANGRY_GLOBAL_VARIABLES:

def process_data(sitename, port=80, numruns=100):
    ...

process_data("Bubba's Blog")

En la práctica, muchos de estos valores serán (o deberían ser) leídos de archivos de configuración, variables de entorno del sistema operativo, argumentos de línea de comando u otras fuentes para satisfacer la inversión del principio / patrón de control . Pero esa es una historia más grande para otro día.

Jonathan Eunice
fuente
1

Sí, es bastante común en la mayoría de los lenguajes de programación (al menos los que uso).

Puede consultar este enlace de Google para compartir un estilo común entre los desarrolladores del mismo equipo.

Se recomienda usar

Type                  |Public          |Internal
Global/Class Constants|CAPS_WITH_UNDER |_CAPS_WITH_UNDER
alain.janinm
fuente