2012-04-28 10 views
8

Sto tentando di creare una funzione per eliminare un'altra funzione.Elimina Funzione

def delete_function(func): 
    del func 

è quello che ho finora, ma per qualche motivo non funziona.

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

non sembra fare il trucco. So che si può fare facilmente, solo

del(foo) 

ma sto cercando di farlo in un modo diverso. Come?

+5

qual è il problema che si spera di risolvere con questa tecnica? – SingleNegationElimination

+1

Infatti. Perché, per l'amore del codice, perché? – Macke

+0

Se devi fare questo, probabilmente c'è qualcosa di sbagliato nella tua implementazione. –

risposta

13

L'eliminazione di una funzione non è realmente qualcosa che si fa alla funzione stessa; si tratta di qualcosa che si fa per lo spazio dei nomi in cui vive. (Proprio come la rimozione del numero 3 da una lista non è qualcosa che si fa per il numero 3, è qualcosa che si fa alla lista.)

Supponiamo voi dicono

def foo(x): return 1 
bar = foo 

Quindi (più o meno) si hanno due nomi, foo e bar, per la stessa identica funzione. Supponiamo ora di chiamare delete_function(foo) o delete_function(bar). La identica cosa, vale a dire un oggetto funzione, viene passato a delete_function.Ma quello che in realtà vuoi rimuovere è l'associazione tra il nome foo o bar e quell'oggetto - e non c'è modo possibile delete_function (comunque lo definisci) puoi sapere se è foo o bar o qualcos'altro che vuoi eliminare di.

(Beh ... In realtà, non c'è. Ci sono brutte cose che si possono fare hacky che avrebbe lasciato il codice delete_function sapere di più su come è stato chiamato. Ma non hanno nemmeno pensare a pensare a loro.)

Così. Le tue opzioni sono le seguenti. (1) Cattive cose hacky, come appena accennato. Non farlo. (2) Passa a delete_function non all'oggetto funzione ma a informazioni sul nome della funzione e su cosa stai cercando di eliminare. Questo è brutto e sgraziato. (3) Non disturbare.

Consiglio vivamente il numero 3, a meno che non sia l'unico motivo per cui si sta facendo questo è di saperne di più su come funziona Python. In quest'ultimo caso, un buon punto di partenza potrebbe essere http://docs.python.org/reference/executionmodel.html.

4

Semplicemente non funzionerà.

cosa si sta cercando di fare è, in sostanza, lo spazio nome del chiamante.

Prova questo:

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

noti che

  1. i locali DICT a 0 e 2 sono identici, e ad 1 quasi - tranne che ha il compito aggiuntivo di foo.
  2. del è una dichiarazione e non una funzione

Se fate la del in una funzione delete_function(), in sostanza, l'assegnazione all'interno della vostra funzione viene rimosso (che è effectless perché la funzione è terminata immediatamente), mentre il chiamante mantiene il compito.

Rigorosamente parlato, del non elimina gli oggetti, ma semplicemente le assegnazioni da nomi agli oggetti. Gli oggetti vengono cancellati "automaticamente" (garbage collection) non appena non vengono più referenziati.

potrebbe funzionare ciò che si tenta di fare mediante ispezione dello stack frame e il passaggio del nome da cancellare come una stringa, ma sarebbe una valle di lacrime.

Forse si tenta

del locals()['foo'] 

o

locals()['foo'] = 42 

? Ma penso che non sia garantito che modifichi realmente il dizionario dei veri locals, potrebbe anche funzionare su una copia e quindi rimanere senza effetto ...

7

Dal foo è una società globale, è possibile eliminarlo dal definizioni globali:

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

+1 Questo è come essere la soluzione più semplice. –

+5

Peccato che la definizione di 'func' che stavi cercando di eliminare non fosse effettivamente nello spazio dei nomi globale. (Ad esempio, perché è all'interno di un'altra funzione.) –

+0

@GarethMcCaughan Sì, questa soluzione è valida solo per le funzioni globali (ma penso che la mia risposta lo chiarisca). –