Treść wyrażenia lambda w python

0

Problem związany z python,

rozszerzam kasę do testów jednostkowych unittest.TestCase o nowe funkcjonalności.
Jedną z funkcjonalności, które dodałem to periodyczne sprawdzanie czy jakaś funkcja zwraca właściwą wartość w ciągu określonego czasu (czekanie, aż zwraca właściwą wartość).
Problem jest w tworzeniu logów. Jeśli do tej metody podana jest funkcja log jest sensowny podaje tylko nazwę funkcji (functObject._ name _).
Jeśli jednak użyje wyrażenie lambda to w logach pojawia mi się "<lambda>" co nie jest dość opisowe.
Potrzebuje wyciągnąć kod tego wyrażenia lambda, by go umieścić w logach.
Jak to zrobić?

obecnie jedna z metod wygląda tak:

    def waitForAsertEqual(self, periodicCheck, expectedValue, msg="", timeout=20, sleep=1) :
        assert(type(periodicCheck) == types.FunctionType or
               type(periodicCheck) == types.LambdaType)
        start = time.time()
        stop = start + timeout
        debug("Waiting for '%s' to return expected value: '%s' in time of %.1fs."
              %(periodicCheck.__name__, expectedValue, timeout))

        while stop > time.time() :
            if periodicCheck() == expectedValue :
                debug("'%s' has returned expected value: '%s' after %.1fs."
                      %(periodicCheck.__name__, expectedValue, time.time()-start))
                return
            time.sleep(sleep)
        debug("waitForAsertEqual has timed out after %ss." %timeout)
        value = periodicCheck()
        self.assertEqual(value, expectedValue, "%s\n"
                                               "Values are different, have value: %s\n"
                                               "               expected value is: %s\n"
                                               %(msg, value, expectedValue))
        return
0

Nie wiem czy jest to możliwe. Możesz wyciągnąć kod w bytekodzie, ale chyba to dużo nie da. Najprawdopodobniej Python nie przechowuje tekstowej formy w pamięci. Spróbuj użyć inspect.getsourcelines(nazwa_funkcji), podczas pisania sprawdziłem, że takie coś działa zgodnie z przewidywaniami:

import inspect
def foo(x):
        return x*x
foo2=lambda x: foo(x)
def foo3(x):
	print inspect.getsourcelines(x)
foo3(foo2)

 
0

Prawie dobrze, to zwraca całą linię kodu nie tylko samo wyrażenie lamda, wiec trzeba to sparsować. Znalezienie początku lambdy to nie problem, gorzej ze znalezieniem końca lambdy (sam przecinek to za mało, bo wywołanie innych funkcji w lambdzie też może mieć przecinek).

0

Może pomocnym okazać się fakt, że aby w lambdzie zapisać wielolinijkowe wyrażenie, to całość (razem ze słowem lambda) powinna zawierać się w nawiasie. Właściwie bloków (po :) w lambdzie nie zapiszesz. Dlatego z if'ami trzeba też się ograniczyć - tylko do tej jednolinijkowej instrukcji: wartość_jeśli_prawda if warunek else wartość_jeśli_fałsz
Może parsowanie nie będzie takie trudne ;) ?

1 użytkowników online, w tym zalogowanych: 0, gości: 1