tabla frecuencias for escribir ecuaciones como python module global

frecuencias - Python: ¿Cómo hacer una variable de módulo cruzado?



for en python (12)

La variable __debug__ es útil en parte porque afecta a todos los módulos. Si quiero crear otra variable que funcione de la misma manera, ¿cómo lo haría?

La variable (seamos originales y lo llamemos ''foo'') no tiene que ser verdaderamente global, en el sentido de que si cambio foo en un módulo, se actualiza en otros. Estaría bien si pudiera establecer foo antes de importar otros módulos y luego verían el mismo valor para él.


Creo que hay muchas circunstancias en las que tiene sentido y simplifica la programación para tener algunos elementos globales conocidos en varios módulos (estrechamente acoplados). Con este espíritu, me gustaría explayarme un poco sobre la idea de tener un módulo de globales que es importado por aquellos módulos que necesitan referenciarlos.

Cuando solo hay uno de esos módulos, lo llamo "g". En él, asigno valores por defecto para cada variable que pretendo tratar como global. En cada módulo que utiliza cualquiera de ellos, no utilizo "from g import var", ya que esto solo da como resultado una variable local que se inicializa desde g solo en el momento de la importación. Hago la mayoría de las referencias en la forma g.var y la "g". sirve como un recordatorio constante de que estoy tratando con una variable potencialmente accesible para otros módulos.

Si el valor de dicha variable global se va a utilizar con frecuencia en alguna función de un módulo, entonces esa función puede hacer una copia local: var = g.var. Sin embargo, es importante darse cuenta de que las asignaciones a var son locales, y global g.var no se puede actualizar sin hacer referencia explícitamente a g.var en una asignación.

Tenga en cuenta que también puede tener múltiples módulos globales compartidos por diferentes subconjuntos de sus módulos para mantener las cosas un poco más controladas. La razón por la que uso nombres cortos para mis módulos globales es para evitar saturar el código demasiado con las ocurrencias de ellos. Con solo un poco de experiencia, se vuelven mnemotécnicos con solo 1 o 2 caracteres.

Todavía es posible hacer una asignación a, digamos, gx cuando x no estaba ya definido en g, y un módulo diferente puede acceder a gx. Sin embargo, aunque el intérprete lo permita, este enfoque no es tan transparente, y evito eso. Todavía existe la posibilidad de crear accidentalmente una nueva variable en g como resultado de un error tipográfico en el nombre de la variable para una tarea. Algunas veces, un examen de dir (g) es útil para descubrir cualquier nombre sorpresa que pueda haber surgido de tal accidente.


Defina un módulo (llámelo "globalbaz") y tenga las variables definidas dentro de él. Todos los módulos que usan este "pseudoglobal" deben importar el módulo "globalbaz", y se refieren a él usando "globalbaz.var_name"

Esto funciona independientemente del lugar del cambio, puede cambiar la variable antes o después de la importación. El módulo importado usará el último valor. (Probé esto en un ejemplo de juguete)

Para aclarar, globalbaz.py se ve así:

var_name = "my_useful_string"


Esto suena como la modificación del espacio de nombre __builtin__ . Para hacerlo:

import __builtin__ __builtin__.foo = ''some-value''

No use __builtins__ directamente (observe las "s" adicionales) - aparentemente esto puede ser un diccionario o un módulo. Gracias a ΤΖΩΤΖΙΟΥ por señalar esto, se puede encontrar más here .

Ahora foo está disponible para usar en cualquier lugar.

No recomiendo hacerlo en general, pero el uso de esto depende del programador.

La asignación debe hacerse como se indicó anteriormente, solo establecer foo = ''some-other-value'' solo lo configurará en el espacio de nombres actual.


Las variables globales generalmente son una mala idea, pero puedes hacer esto asignando a __builtins__ :

__builtins__.foo = ''something'' print foo

Además, los módulos mismos son variables a las que puede acceder desde cualquier módulo. Entonces, si defines un módulo llamado my_globals.py :

# my_globals.py foo = ''something''

Entonces puedes usar eso desde cualquier lugar también:

import my_globals print my_globals.foo

Usar módulos en lugar de modificar __builtins__ es generalmente una forma más limpia de hacer globales de este tipo.


Me preguntaba si sería posible evitar algunas de las desventajas del uso de variables globales (véase, por ejemplo, http://wiki.c2.com/?GlobalVariablesAreBad ) mediante el uso de un espacio de nombres de clase en lugar de un espacio de nombres global / módulo para pasar los valores de las variables . El siguiente código indica que los dos métodos son esencialmente idénticos. Hay una ligera ventaja en el uso de espacios de nombres de clase como se explica a continuación.

Los siguientes fragmentos de código también muestran que los atributos o variables se pueden crear y eliminar dinámicamente en los espacios de nombres globales / de módulo y en los espacios de nombres de clase.

wall.py

# Note no definition of global variables class router: """ Empty class """

Yo llamo a este módulo ''muro'' ya que se usa para rechazar variables. Actuará como un espacio para definir temporalmente las variables globales y los atributos de toda la clase del "enrutador" de la clase vacía.

source.py

import wall def sourcefn(): msg = ''Hello world!'' wall.msg = msg wall.router.msg = msg

Este módulo importa wall y define una única función sourcefn que define un mensaje y lo emite mediante dos mecanismos diferentes, uno vía globales y otro a través de la función del enrutador. Tenga en cuenta que las variables wall.msg y wall.router.message se definen aquí por primera vez en sus respectivos espacios de nombres.

dest.py

import wall def destfn(): if hasattr(wall, ''msg''): print ''global: '' + wall.msg del wall.msg else: print ''global: '' + ''no message'' if hasattr(wall.router, ''msg''): print ''router: '' + wall.router.msg del wall.router.msg else: print ''router: '' + ''no message''

Este módulo define una función destfn que utiliza los dos mecanismos diferentes para recibir los mensajes emitidos por la fuente. Permite la posibilidad de que la variable ''msg'' no exista. destfn también elimina las variables una vez que se han mostrado.

main.py

import source, dest source.sourcefn() dest.destfn() # variables deleted after this call dest.destfn()

Este módulo llama a las funciones previamente definidas en secuencia. Después de la primera llamada a dest.destfn las variables wall.msg y wall.router.msg ya no existen.

El resultado del programa es:

global: ¡Hola mundo!
enrutador: ¡Hola mundo!
global: sin mensaje
enrutador: sin mensaje

Los fragmentos de código anteriores muestran que los mecanismos de variables módulo / global y clase / clase son esencialmente idénticos.

Si se van a compartir muchas variables, la contaminación del espacio de nombres se puede gestionar ya sea mediante el uso de varios módulos de pared, por ejemplo, wall1, wall2, etc. o definiendo varias clases de enrutadores en un solo archivo. Este último es un poco más ordenado, por lo que quizás represente una ventaja marginal para el uso del mecanismo de variable de clase.


No apruebo esta solución de ninguna manera, forma o forma. Pero si agrega una variable al módulo __builtin__ , se podrá acceder como si fuera un elemento global de cualquier otro módulo que incluya __builtin__ - que es todos ellos, de forma predeterminada.

a.py contiene

print foo

b.py contiene

import __builtin__ __builtin__.foo = 1 import a

El resultado es que se imprime "1".

Editar: El módulo __builtin__ está disponible como el símbolo local __builtins__ - ese es el motivo de la discrepancia entre dos de estas respuestas. También tenga en cuenta que __builtin__ ha sido renombrado como builtins en python3.


Pude lograr variables modificables en varios módulos (o mutables ) usando un diccionario:

# in myapp.__init__ Timeouts = {} # cross-modules global mutable variables for testing purpose Timeouts[''WAIT_APP_UP_IN_SECONDS''] = 60 # in myapp.mod1 from myapp import Timeouts def wait_app_up(project_name, port): # wait for app until Timeouts[''WAIT_APP_UP_IN_SECONDS''] # ... # in myapp.test.test_mod1 from myapp import Timeouts def test_wait_app_up_fail(self): timeout_bak = Timeouts[''WAIT_APP_UP_IN_SECONDS''] Timeouts[''WAIT_APP_UP_IN_SECONDS''] = 3 with self.assertRaises(hlp.TimeoutException) as cm: wait_app_up(PROJECT_NAME, PROJECT_PORT) self.assertEqual("Timeout while waiting for App to start", str(cm.exception)) Timeouts[''WAIT_JENKINS_UP_TIMEOUT_IN_SECONDS''] = timeout_bak

Al iniciar test_wait_app_up_fail , la duración del tiempo de espera real es de 3 segundos.


Puede pasar los globales de un módulo a otro:

En el Módulo A:

import module_b my_var=2 module_b.do_something_with_my_globals(globals()) print my_var

En el Módulo B:

def do_something_with_my_globals(glob): # glob is simply a dict. glob["my_var"]=3


Quería publicar una respuesta de que hay un caso en el que no se encontrará la variable.

Las importaciones cíclicas pueden romper el comportamiento del módulo.

Por ejemplo:

first.py

import second var = 1

second.py

import first print(first.var) # will throw an error because the order of execution happens before var gets declared.

main.py

import first

En este ejemplo, debería ser obvio, pero en una gran base de código, esto puede ser realmente confuso.


Si necesita una variable global de módulo cruzado, tal vez sea suficiente una simple variable global de nivel de módulo.

a.py:

var = 1

b.py:

import a print a.var import c print a.var

c.py:

import a a.var = 2

Prueba:

$ python b.py # -> 1 2

Ejemplo del mundo real: global_settings.py de Django (aunque en la configuración de las aplicaciones de Django se utiliza la importación del objeto django.conf.settings ).


Utilizo esto para un par de funciones primitivas integradas que realmente sentía que faltaban. Un ejemplo es una función de búsqueda que tiene la misma semántica de uso que filter, map, reduce.

def builtin_find(f, x, d=None): for i in x: if f(i): return i return d import __builtin__ __builtin__.find = builtin_find

Una vez que esto se ejecuta (por ejemplo, al importar cerca de su punto de entrada) todos sus módulos pueden usar find () como si, obviamente, estuviera integrado.

find(lambda i: i < 0, [1, 3, 0, -5, -10]) # Yields -5, the first negative.

Nota: Puedes hacer esto, por supuesto, con filtro y otra línea para probar la longitud cero, o con reducir en un tipo de línea extraña, pero siempre sentí que era extraño.


Ya puede hacer esto con variables de nivel de módulo. Los módulos son los mismos sin importar de qué módulo se importen. De modo que puede hacer que la variable sea una variable a nivel de módulo en cualquier módulo que tenga sentido ponerlo, y acceder a él o asignarlo desde otros módulos. Sería mejor llamar a una función para establecer el valor de la variable, o para que sea una propiedad de algún objeto singleton. De esta forma, si necesita ejecutar algún código cuando la variable ha cambiado, puede hacerlo sin romper la interfaz externa de su módulo.

Usualmente no es una gran manera de hacer cosas, el uso de globals rara vez lo es, pero creo que esta es la forma más limpia de hacerlo.