2010-08-10 13 views
5

Piszę niektóre testy jednostkowe (za pomocą modułu unittest) dla mojej aplikacji i chcę napisać coś, co może potwierdzić, że metoda, którą wywołuję, zwraca obiekt "podobny do pliku". Ponieważ nie jest to proste wywołanie isinstance, zastanawiam się, jaka byłaby najlepsza praktyka do określenia tego?Python: ustalenie, czy obiekt jest podobny do pliku?

Tak w zarysie:

possible_file = self.dao.get_file("anotherfile.pdf") 
self.assertTrue(possible_file is file-like) 

Może muszę dbać których specyficzny interfejs ten plik narzędzi obiekt lub jakie metody, które czynią go plikopodobny chcę wspierać?

Dzięki

R

Odpowiedz

2

Sprawdź, czy zwrócony obiekt zapewnia interfejs szukasz. Jak to na przykład:

self.assert_(hasattr(possible_file, 'write')) 
self.assert_(hasattr(possible_file, 'read')) 
+1

Nie rób tego, chyba że jesteś pewien, że tego chcesz. – katrielalex

+0

Tak, cóż, nie zrobiłbym tego. Ale poprosił o sposób sprawdzenia, czy coś jest w pliku, aby nie używać go jako pliku. – gruszczy

4

Klasyczny Python mentalność jest to, że łatwiej prosić o przebaczenie niż pozwolenie. Innymi słowy, nie sprawdzaj, przechwytuj wyjątek spowodowany przez write.

Nowy sposób polega na użyciu testu IO abstract base class w czeku isinstance. Zostało to wprowadzone, gdy ludzie zorientowali się, że pisanie kaczek jest niesamowite, ale czasami naprawdę zależy Ci na sprawdzeniu instancji.

W twoim przypadku (test jednostkowy), prawdopodobnie chcesz, aby spróbować i zobaczyć:

thingy = ... 
try: 
    thingy.write(...) 
    thingy.writeline(...) 
    ... 
    thingy.read() 
except AttributeError: 
    ... 
+2

próba zapisu do pliku może nie być odpowiednia w kontekście testu jednostkowego. –

+0

+1 dla klasycznych i renesansowych wzorców myślowych –

+0

@Ned: really? Jeśli wdrażasz klasę podobną do pliku, z pewnością powinieneś przetestować, czy to * powoduje * zapisywanie tego, co ją podajesz? Ale jeśli naprawdę tego nie chcesz, możesz użyć 'hasattr'. – katrielalex

7

Nie ma „oficjalnej definicji” o jakie obiekty są „wystarczająco plikopodobny”, ponieważ w różnych zastosowaniach obiekty podobne do plików mają różne wymagania - np. niektóre wymagają tylko metod: read lub write, inne wymagają pewnego podzbioru różnych metod czytania linii ... wszystkich sposobów wymagających użycia metody fileno, która nie może być nawet dostarczane przez "obiekty bardzo podobne do plików" oferowane przez moduły StringIO i cStringIO w standardowej bibliotece. To z pewnością kwestia "odcieni szarości", a mianowicie czarno-białej taksonomii!

Musisz więc określić, które metody są ci potrzebne. Aby je sprawdzić, zaleciłem zdefiniowanie własnych dekoratorów i sprawdzanie obiektu za pomocą isinstance dla tej klasy, jeśli używasz Pythona w wersji 2.6 lub nowszej: jest to obecnie zalecany język, a nie kilka hasattr kontrole, które byłyby mniej czytelne i bardziej złożone (gdy odpowiednio udoskonalono by kontrole, że te atrybuty są w rzeczywistości metodami itp ;-).

+0

Cześć Alex, Dzięki za wskazówkę, to jest interesujące rzeczy, chociaż wciąż mam o tym głowę. Czy sugerujesz użycie tego po prostu dla unittest, czy też powinno to być ogólne podejście do zarządzania obiektami podobnymi do plików wewnątrz aplikacji? –

+0

@Richard, ledwie "staję się mokra" dzięki produkcyjnemu użyciu ABC w Pythonie (chociaż analogie z typograficznymi Haskell, abstrakcyjne klasy bazowe C++, interfejsy Java itp. Pomagają mi ;-), więc mogę " t (jeszcze) zdecydowanie polecają je lub w inny sposób w tym kontekście. Myślę, że będą w porządku (znowu przez analogię z alternatywami, które znam bardzo dobrze), ale potrzebuję trochę więcej prawdziwego świata z nimi "pod moim pasem", aby czuć się naprawdę pewnie ;-). Ale, dla celów testowych, już wiem, że to "piżama kota", to znaczy, że jest naprawdę doskonała i użyteczna. –

+0

arg - brak znaczników kodu w komentarzach! –

Powiązane problemy