2010-08-10 25 views
5

Estoy escribiendo algunas pruebas de unidad (usando el módulo unittest) para mi aplicación, y quiero escribir algo que pueda verificar que un método al que llamo devuelva un objeto "similar a un archivo". Como esta no es una simple llamada de instancia, me pregunto cuál sería la mejor práctica para determinar esto.Python: determinar si un objeto es similar a un archivo

Así, a grandes rasgos:

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

Tal vez tiene que cuidar la interfaz que implementa este objeto de archivo, o que los métodos que hacen que sea de tipo fichero quiero apoyar específico?

Gracias,

R

Respuesta

2

Comprobar, si el objeto devuelto proporciona una interfaz que busca. Así por ejemplo:

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

No haga esto a menos que estés _sure_ que lo desee. – katrielalex

+0

Sí, bueno, yo no haría eso. Pero pidió una forma de verificar, si algo es un archivo, para no usarlo como un archivo. – gruszczy

4

La mentalidad clásica de Python es que es más fácil pedir perdón que permiso. En otras palabras, no marque, atrape la excepción causada por write.

La nueva forma es usar un IO abstract base class en un cheque isinstance. Esto se introdujo cuando la gente se dio cuenta de que la tipificación de pato es impresionante, pero a veces realmente quieres una verificación de instancia.

En su caso (prueba unitaria), es probable que desee probar y ver:

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

tratando de escribir en el archivo puede no ser apropiado en un contexto de prueba de unidad. –

+0

+1 para patrones de pensamiento clásico y renacentista –

+0

@Ned: ¿en serio? Si está implementando una clase similar a un archivo, seguramente debería probar que * ¿* escribe lo que le da? Pero si realmente no quieres eso, entonces puedes usar 'hasattr'. – katrielalex

7

No hay ninguna "definición oficial" de lo que los objetos son "suficientemente tipo fichero", debido a los diversos usos de objetos de archivo similar tienen tales requisitos diferentes - por ejemplo, algunos sólo requieren read o write métodos, otros requieren algún subconjunto de los diversos métodos de alineación de lectura ... todas las formas de algunos que requiere el método fileno, que ni siquiera puede ser suministrado por los "objetos muy similares a archivos" ofrecidos por los módulos StringIO y cStringIO en la biblioteca estándar. Definitivamente es una cuestión de "tonos de gris", no ¡una taxonomía en blanco y negro!

Por lo tanto, debe determinar qué métodos necesita. Para verificarlos, recomendé definir su propio FileLikeEnoughForMeabstract base class con decoradores abstractmethod, y verificar el objeto con un isinstance para esa clase, si está en Python 2.6 o mejor: este es el idioma recomendado en estos días, en lugar de un montón de hasattr cheques que serían menos legibles y más complejos (cuando se refuerzan adecuadamente con cheques que esos atributos son realmente métodos, etc ;-).

+0

Hola Alex, gracias por el puntero, esto es algo interesante, aunque todavía estoy entendiendo. ¿Sugiere simplemente usar esto para la prueba unitaria o debería ser un enfoque general para administrar objetos similares a archivos dentro de una aplicación? –

+0

@Richard, apenas estoy "mojándome los pies" con el uso de producción de ABCs en Python (aunque las analogías con las clases de Haskell, las clases base abstractas de C++, las interfaces Java, etc., me ayudan ;-) para que pueda ' t (aún) lo recomienda sólidamente o de otra forma en ese contexto. Creo que estarán bien (de nuevo por analogía con las alternativas que conozco muy bien) pero necesito un poco más de lucha real con ellos "bajo mi cinturón" para sentirme realmente confiado de cualquier manera ;-). Pero, para fines de prueba, ya sé que son "pijamas del gato", es decir, excelentes y útiles. –

+0

arg - ¡sin marcado de código en los comentarios! –

Cuestiones relacionadas