nonlocal - ¿Utiliza la declaración "global" en Python?
python multiple global variables (12)
Estaba leyendo una pregunta sobre la declaración global de Python ( "alcance de Python" ) y estaba recordando la frecuencia con que usé esta declaración cuando era un principiante de Python (utilicé mucho global ) y cómo, hoy en día, años más tarde, yo don no lo uso en absoluto, nunca. Incluso lo considero un poco "antiponético".
¿Usas esta declaración en Python? ¿Tu uso de esto ha cambiado con el tiempo?
En mi opinión, tan pronto como sienta la necesidad de usar variables globales en un código python, es un buen momento para detenerse un poco y trabajar en la refacturación de su código.
Poner lo global
en el código y retrasar el proceso de refactorización puede sonar prometedor si su fecha límite está cerca, pero, créame, no va a volver a esto y solucionarlo a menos que realmente tenga que hacerlo, como que su código dejó de funcionar para Por alguna extraña razón, tienes que depurarlo, te encuentras con algunas de esas variables global
y todo lo que hacen es complicar las cosas.
Así que, honestamente, incluso está permitido, yo preferiría evitar usarlo. Incluso si esto significa una simple construcción de clases alrededor de tu pedazo de código.
Lo evito e incluso tenemos una regla de pylint que lo prohíbe en nuestro código de producción. De hecho, creo que ni siquiera debería existir.
Lo he usado en scripts rápidos y sucios, de un solo uso para automatizar alguna tarea de una sola vez. Algo más grande que eso, o que necesite ser reutilizado, y voy a encontrar una manera más elegante.
Lo he usado en situaciones donde una función crea o establece variables que se usarán globalmente. Aquí hay unos ejemplos:
discretes = 0
def use_discretes():
#this global statement is a message to the parser to refer
#to the globally defined identifier "discretes"
global discretes
if using_real_hardware():
discretes = 1
...
o
file1.py:
def setup():
global DISP1, DISP2, DISP3
DISP1 = grab_handle(''display_1'')
DISP2 = grab_handle(''display_2'')
DISP3 = grab_handle(''display_3'')
...
file2.py:
import file1
file1.setup()
#file1.DISP1 DOES NOT EXIST until after setup() is called.
file1.DISP1.resolution = 1024, 768
Lo uso para opciones globales con scripts de línea de comandos y ''optparse'':
my main () analiza los argumentos y los pasa a cualquier función que haga el trabajo del script ... pero escribe las opciones suministradas en un diccionario global ''opts''.
Las opciones de script de Shell a menudo modifican el comportamiento de ''hoja'', y es inconveniente (e innecesario) pasar el diccionario ''opts'' a través de cada lista de argumentos.
Los objetos son la forma preferida de tener un estado no local, por lo que global es raramente necesario. No creo que el próximo modificador no local vaya a ser ampliamente utilizado tampoco, creo que está principalmente allí para hacer que los liskers dejen de quejarse :-)
Nunca he tenido un uso legítimo para la declaración en ningún código de producción en mis más de 3 años de uso profesional de Python y más de cinco años como aficionado de Python. Cualquier estado que necesite cambiar reside en clases o, si hay algún estado "global", se encuentra en alguna estructura compartida como una caché global.
Puede ser útil en subprocesos para compartir estado (con mecanismos de bloqueo a su alrededor).
Sin embargo, rara vez lo uso.
Raramente. Todavía tengo que encontrar un uso para eso.
Si puedo evitarlo, no. Y, que yo sepa, siempre hay una manera de evitarlo. Pero no afirmo que sea totalmente inútil
Una o dos veces. Pero siempre fue un buen punto de partida para refactorizar.
Uso ''global'' en un contexto como este:
_cached_result = None
def myComputationallyExpensiveFunction():
global _cached_result
if _cached_result:
return _cached_result
# ... figure out result
_cached_result = result
return result
Uso ''global'' porque tiene sentido y es claro para el lector de la función lo que está sucediendo. También sé que existe este patrón, que es equivalente, pero le da más carga cognitiva al lector:
def myComputationallyExpensiveFunction():
if myComputationallyExpensiveFunction.cache:
return myComputationallyExpensiveFunction.cache
# ... figure out result
myComputationallyExpensiveFunction.cache = result
return result
myComputationallyExpensiveFunction.cache = None