2012-04-28 17 views
8

Estoy intentando crear una función para eliminar otra función.Borrar Función

def delete_function(func): 
    del func 

es lo que tengo hasta ahora, pero por alguna razón no funciona.

def foo(): 
    print("foo") 
delete_function(foo) 

no parece hacer el truco. Sé que uno puede hacerlo fácilmente, solo

del(foo) 

pero estoy tratando de hacerlo de otra manera. ¿Cómo?

+5

¿cuál es el problema que espera resolver con esta técnica? – SingleNegationElimination

+1

De hecho. ¿Por qué, por amor al código, por qué? – Macke

+0

Si tiene que hacer esto, es probable que haya algún problema con su implementación. –

Respuesta

13

Eliminar una función no es algo que se le ocurra a la función en sí; que es algo que se hace para el espacio de nombres que vive. (Así como la eliminación del número 3 de la lista no es algo que se hace con el número 3, que es algo que se hace a la lista.)

suponga que dicen

def foo(x): return 1 
bar = foo 

Luego, (más o menos) tiene dos nombres, foo y bar, para exactamente la misma función. Ahora suponga que llama al delete_function(foo) o delete_function(bar). El exactamente lo mismo, es decir, un objeto de función, se pasa al delete_function.Pero lo que realmente quiere eliminar es la asociación entre el nombre foo o bar y ese objeto, y no hay manera posible de que delete_function (como usted lo defina) pueda saber si es foo o bar o algo más que quiere deshacerse de.

(Bueno ... En realidad, no existe. Hay cosas desagradables hacky que puede hacer que permitiría el código en delete_function saber más acerca de cómo se llamaba. Pero ni siquiera piensan acerca de pensar en ellos.)

So. Tus opciones son las siguientes. (1) Nasty cosas desagradables, como acabo de mencionar. No lo hagas (2) Pase delete_function no es el objeto de la función, sino la información sobre el nombre de la función y de lo que intenta eliminar. Esto es feo y desgarbado. (3) No te molestes.

Recomiendo encarecidamente # 3, a menos que la única razón por la que está haciendo esto es para aprender más sobre cómo funciona Python. En este último caso, un buen lugar para comenzar podría ser http://docs.python.org/reference/executionmodel.html.

4

Simplemente no funcionará.

Lo que estás tratando de hacer es, esencialmente, el espacio de nombre de la persona que llama.

Prueba esto:

print "0", locals() 
def foo(): pass 
print "1", locals() 
del foo 
print "2", locals() 

Tenga en cuenta que

  1. los locales dict a 0 y 2 son idénticos, y en casi 1 - excepto que tiene la asignación adicional de foo.
  2. del es una declaración y no una función

Si lo hace el del en una función delete_function(), esencialmente la asignación dentro de su función consigue quitado (que es effectless porque la función se termina inmediatamente), mientras que la persona que llama mantiene la tarea.

Hablando en sentido estricto, del no elimina objetos, sino simplemente asignaciones de nombres a objetos. Los objetos se eliminan "automáticamente" (basura recolectada) tan pronto como ya no se hace referencia a ellos.

PODRÍA funcionar lo que intenta hacer inspeccionando el marco de pila y pasando el nombre que se eliminará como una cadena, pero sería un PITA.

Tal vez intenta

del locals()['foo'] 

o

locals()['foo'] = 42 

? Pero creo que no está garantizado que realmente modifique el diccionario local real, también podría funcionar en una copia y así no tener ningún efecto ...

7

Desde foo es una global, puede eliminarla de las definiciones globales:

def delete_func(func): 
    del globals()[func.func_name] 
+0

+1 Esto es como ser la solución más simple. –

+5

Es una lástima si la definición de 'func' que estaba tratando de eliminar no está realmente en el espacio de nombres global. (Por ejemplo, porque está dentro de otra función). –

+0

@GarethMcCaughan Sí, esta solución solo sirve para funciones globales (pero creo que mi respuesta lo deja bastante claro). –