2010-09-11 18 views
7

ho ottenuto una funzione in un certo modulo che voglio ridefinire (finto) in fase di esecuzione a scopo di test. Per quanto ho capito, la definizione della funzione non è altro che un compito in python (la definizione del modulo stessa è un tipo di funzione che viene eseguita). Come ho detto, voglio farlo nell'impostazione di un caso di test, quindi la funzione deve essere ridefinita in un altro modulo. Qual è la sintassi per fare questo? Per esempio, 'module1' è il mio modulo e 'func1' è la mia funzione, nel mio testcase Ho provato questo (senza successo):Come ridefinire le funzioni in python?

import module1 

module1.func1 = lambda x: return True 
+2

non è necessario 'return' in' lambda'. 'module1.func1 = lambda x: True' dovrebbe funzionare. – sastanin

risposta

9
import module1 
import unittest 

class MyTest(unittest.TestCase): 
    def setUp(self): 
     # Replace othermod.function with our own mock 
     self.old_func1 = module1.func1 
     module1.func1 = self.my_new_func1 

    def tearDown(self): 
     module1.func1 = self.old_func1 

    def my_new_func1(self, x): 
     """A mock othermod.function just for our tests.""" 
     return True 

    def test_func1(self): 
     module1.func1("arg1") 

sacco di finto le librerie forniscono gli strumenti per fare questo tipo di derisione, dovresti investigarle perché probabilmente avrai una buona dose di aiuto da loro.

+0

Sai se posso ridefinire la funzione usando una chiusura? –

+0

Si potrebbe anche usare un lambda come avete fatto nel tuo esempio, non deve essere un metodo. –

2

Basta assegnare una nuova funzione o lambda al vecchio nome:

>>> def f(x): 
...  return x+1 
... 
>>> f(3) 
4 
>>> def new_f(x): 
...  return x-1 
... 
>>> f = new_f 
>>> f(3) 
2 

funziona anche quando una funzione è da un altro modulo:

### In other.py: 
# def f(x): 
# return x+1 
### 

import other 

other.f = lambda x: x-1 

print other.f(1) # prints 0, not 2 
+0

Come ho già detto, la funzione è in un altro modulo, controlla la mia modifica. –

+0

Funziona allo stesso modo. Ho aggiornato la risposta. – sastanin

3
import foo 

def bar(x): 
    pass 

foo.bar = bar 
+0

La soluzione più semplice e migliore. – Depado

1

Se si desidera ricaricare nel foo.py file di interprete che si sta modificando, è possibile effettuare una semplice da tipo di funzione e l'uso execfile(), ma ho appena imparato che non funziona senza l'elenco globale di tutte le funzioni (purtroppo), a meno che qualcuno ha un'idea migliore:

Da qualche parte nel file di foo.py:

def refoo(): 
    global fooFun1, fooFun2 
    execfile("foo.py") 

nella interprete Python:

refoo() # Ora avete le vostre ultime modifiche da foo.py

2

Uso REDEF: http://github.com/joeheyming/redef

import module1 
from redef import redef 

rd_f1 = redef(module1, 'func1', lambda x: True) 

Quando rd_f1 va fuori ambito o viene eliminata , func1 sarà tornare ad essere di nuovo al normale

+0

Ho pensato portata ref-contato era una cosa CPython, e questo genere di cose non avrebbe funzionato su altre piattaforme (PyPy, Jython, IronPython). – leewz

+0

all redef fa è wrap una funzione o attributo con una nuova funzione/attributo. quando l'oggetto esce dall'ambito, viene chiamata la funzione __delete__, che ripristina la dichiarazione della funzione su utilizzando la funzione/attributo precedente. Questo non è un tipo di oggetto di portata conteggiato per ref. –

+0

Ma l'idea di "oggetto viene segnalato quando va fuori del campo di applicazione" dipende CPython ref-conteggio, no? Per esempio, in PyPy, quando la variabile di un oggetto file va fuori del campo di applicazione, l'oggetto non è garbage collection subito, in modo che il file non è chiuso fino a quando il collezionista decide di. – leewz

Problemi correlati