2011-01-07 14 views
10

Estoy usando una lista en la que algunas funciones funcionan en mi programa. Esta es una lista compartida en realidad y todas mis funciones pueden editarla. ¿Es realmente necesario definirlo como "global" en todas las funciones?Definición de listas como variables globales en Python

Me refiero a poner la palabra clave global detrás de ella en cada función que lo usa, o definirla fuera de todas las funciones es suficiente sin usar la palabra global detrás de su definición?

+5

Por supuesto que sabe que las variables globales son eeeevil? Cuando sea posible, no escriba una función que dependa de algo más que los argumentos. Y nunca, a menos que en circunstancias muy excepcionales, modifique algo global desde más de un punto. Casi nunca es necesario y es propenso a agregar grandes dolores de cabeza más adelante. En conclusión, no vale la pena. – delnan

Respuesta

22

Cuando se asigna una variable (x = ...), que está creando una variable en el ámbito actual (por ejemplo, local a la función actual). Si sucede sombrear una variable de un ámbito externo (por ejemplo, global), es una lástima: a Python no le importa (y eso es bueno). Entonces usted no puede hacer esto:

x = 0 
def f(): 
    x = 1 
f() 
print x #=>0 

y espera 1. En cambio, necesita no declara que va a utilizar el global x:

x = 0 
def f(): 
    global x 
    x = 1 
f() 
print x #=>1 

Pero tenga en cuenta que la asignación de una variable es muy diferente de las llamadas a métodos. Siempre puede llamar a los métodos sobre cualquier cosa dentro del alcance, p. Ej. en variables que provienen de un ámbito externo (por ejemplo, el global) porque nada local las sombrea.

también muy importante: la asignación miembro (x.name = ...), misiones artículo (collection[key] = ...), misiones rebanada (sliceable[start:end] = ...) y además probablemente más están llamadas a métodos, así! Y, por lo tanto, no necesita global para cambiar los miembros de un global o llamarlo métodos (incluso cuando mutan el objeto).

+4

+1. También vale la pena señalar que las asignaciones de sectores no sobrescribirán la referencia. En particular, en lugar de 'x = newlist', uno puede hacer' x [:] = new_list' y todavía no necesita usar 'global'. Esto, por supuesto, está cubierto por el caso de llamada al método, pero vale la pena señalar explícitamente. – aaronasterling

+0

@aaron: Sí. Ampliado para dejar en claro que hay muchas cosas (incluida la asignación de miembros, la asignación de sectores, etc.) que en realidad son llamadas de método. – delnan

4

Sí, necesita usar global foo si va a escribir en él.

foo = [] 

def bar(): 
    global foo 
    ... 
    foo = [1] 
+1

Aunque no es estrictamente incorrecto (en el ejemplo, es necesario 'global'), esto es engañoso. Para empezar, muchos parecen estar en desacuerdo con la noción de Python de cuándo "escribes". – delnan

+0

gracias, ¿es este también el caso de los diccionarios? – Hossein

+2

@Hossein: es lo mismo para cualquier variable. El objeto al que se hace referencia no importa. – delnan

1

No, puede especificar la lista como un argumento de palabra clave para su función.

alist = [] 
def fn(alist=alist): 
    alist.append(1) 
fn() 
print alist # [1] 

Yo diría que es una mala práctica. Algo demasiado hackish. Si realmente necesita utilizar una estructura de datos de tipo singleton disponible globalmente, usaría el enfoque de variable de nivel de módulo, es decir, ponga 'alist' en un módulo y luego en sus otros módulos importe esa variable:

En archivo foomodule.py:

alist = [] 

En barmodule.py archivo:

import foomodule 
def fn(): 
    foomodule.alist.append(1) 
print foomodule.alist # [1] 
+0

Aclaración: "Globals" son * siempre * a nivel de módulo. No es necesario colocarlo en un módulo adicional (a veces útil o semánticamente más correcto). – delnan

+0

No estaba al tanto de las complejidades involucradas. Parece que los dos ejemplos que escribí no son necesarios en absoluto si todo lo que quiere hacer es modificar una variable de nivel de módulo (es decir, no hacer una asignación al nombre global). Vea la respuesta de Delnan para una evaluación mucho mejor. – XORcist