2011-03-01 25 views
5

Prefacio: Hasta ahora he utilizado python como un lenguaje de programación a gran escala. Ahora me gusta utilizarlo para escribir algunas notas (comentarios) con algún cálculo (código python) aquí y allá (en realidad estoy usando emacs y envío el búfer actual una y otra vez a una instancia de ipython en ejecución).Bloques de código anónimo

El problema: me gusta reutilizar varias veces nombres de variables comunes como 'A' o 'd' varias veces dentro del mismo documento sin correr el problema de olvidar reasignar el valor a uno de estos nombres de variable.

hasta ahora abusan de la declaración de clase

# Topic one: bla bla 
class _anon: 
    d = 10 
    A = d**2 * pi /4 

# Topic two: bla bla 
class _anon: 
    A = d**2 * pi /4 # error is raised since d is missing 

Esto funciona, ya que una declaración de clase crea un marco de ejecución que funciona como un ámbito de variable, pero me pregunto si hay sintaxis específica para este caso de uso.

Respuesta

3

No. Solo class y def bloques y módulos (y en versiones más recientes, listas de comprensión y expresiones de generador, aunque aquí no son aplicables) introducen un nuevo alcance. Y solo las clases se ejecutan directamente. Entonces, si desea continuar con este uso discutible de Python, deberá seguir abusando de class, o definir funciones y llamarlas directamente. Usar un archivo diferente para cada cálculo es ligeramente menos feo en el nivel del código fuente, pero no vale la pena si los cálculos son siempre tan pequeños.

+0

Supongo que sí. Gracias por la confirmación. –

2

globals.clear()casi obras:

>>> a = 5 
>>> b = 6 
>>> a 
5 
>>> b 
6 
>>> globals().clear() 
>>> a 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'a' is not defined 
>>> b 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'b' is not defined 

El problema es que va a volar lejos de todo, incluyendo cosas útiles como globals sí mismo! Si se intenta hacer globals.clear() una segunda vez, verá:

>>> globals.clear() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'globals' is not defined 

Para una solución a esto, ve http://bytes.com/topic/python/answers/34902-how-clean-python-interpreters-environment#post129239

Pero si yo fuera a tantos problemas para doblar Python a la existencia de un cálculo motor, me pregunto si hay mejores herramientas para el propósito como GNU Octave.

+0

Oh, no sabía eso: D Pero tengo algunos parámetros globales que uso en todos los calcs. Sin embargo, esto es ciertamente útil en las sesiones interactivas de ipython. +1 –

+0

Acabo de probarlo con ipython y allí globals.clear() no se suicida. Funciona según lo previsto. –

+0

Soy bastante fluido con matlab y no estoy al tanto de que matlab tenga bloques de código anónimos al lado de las funciones. Supongo que esto también es cierto para Octave, ya que está destinado a ser y reemplazar al matlab. –

2

Siempre se puede eliminar de forma explícita sus valores después de cada bloque, con del

d = 10 
A = d**2 * pi /4 
(...) 
del d, A 

# Topic two: bla bla 

A = d**2 * pi /4 # error is raised since d is missing 

"Explícito es mejor que implícito." "La legibilidad cuenta". "Debería haber una, y preferiblemente solo una, forma obvia de hacerlo".

Si desea cosas sofisticadas, es posible realizar pruebas unitarias que fallan si una "variable de una letra" está viva "demasiado lejos del punto en que se creó" pruebas de escritura que permiten que el seguimiento de depuración verifique eso. De esta forma, no olvidaría agregar las declaraciones del.

+1

Una respuesta válida. Eso es lo que hago en los scripts de Matlab. Pero es muy propenso a errores. Los bloques {} de C++ me arruinan. –

2

Si quiero simular C/bloques C++, esto por lo general hace el truco:

def _anon(): 
    d = 10 
    A = d**2 * pi /4 
_anon() 

Estos "bloques" son capaces de anidar.


Si un pequeño trozo de texto modelo inicial es aceptable, también se puede utilizar un decorador de llamar a la función:

def block(function): 
    function() 

Ahora usted no tiene que repetir su nombre:

@block 
def _anon(): 
    d = 10 
    A = d**2 * pi /4 

Tenga en cuenta que los decoradores de funciones generalmente devuelven una función, pero esta no. El resultado es que el nombre "_anon" apunta a "Ninguno" después de ejecutar el código, por lo que el bloque de código es realmente anónimo.

Cuestiones relacionadas