Comprobar la clase del parametro de una funcion

Joaquin Jose del Cerro Murciano jjdelcerromurciano en yahoo.es
Lun Mayo 23 17:59:03 CEST 2005


Hola, 

Asi a bote pronto, te iba entendiendo la pregunta asta que pusiste el ejemplo, 
que no lo entiendo.

Si vienes de C, supongo que lo que quieres es que el compilador, en tiempo de 
compilacion, te avise de que a una funcion le has pasado unos parametros que 
no son lo que toca. De ser eso lo que quieres, en python, vas apañao. Python 
se caracteriza precisamente por que no hay comprobacion que valga, tu le 
pasas "algo" que si ese algo se parece a lo que esperas la cosa funciona. 
Esto a los programadores de java puristas les saca un tanto de quizio, pero 
eso es python. Ahora bien, puedes intentar pasarle al codigo fuente algun 
tipo de herramienta que realice chequeos para comprobar esas cosas asta donde 
pueda hacerlo. Yo he visto el "pylint" y "pychecker", y he usado con bastante 
frecuencia el pychecker para comprobar que no se me ha ido la mano de manera 
exajerada en el codigo.

Si estas usando python 2.4, tienes otra alternativa "mas pythonica", usar 
decoradores. Estos te permitirian comprobar de forma mas o menos automatizada 
que los parametros que recibes son del tipo que tocan; pero siempre en tiempo 
de ejecucion. Basicamente, y segun lo veo yo, te ahorran un monton de faena 
engorrosa, ya que pasas de poner codigo para comprobar los parametros, que lo 
hagan ellos. Puedes encontrar informacion sobre ellos en la PEP 318, 
http://www.python.org/peps/pep-0318.html, y concretamente en lo que a ti te 
atañe te pego un pedazo de codigo extraido de alli.


Por un lado defines los decoradores, puedes meterlos en un modulo y 
simplemente importarlo donde los necesites.

def accepts(*types):
    def check_accepts(f):
        # Aqui me he comido una linea que no tengo claro que funcione.
        def new_f(*args, **kwds):
            for (a, t) in zip(args, types):
                assert isinstance(a, t), \
                       "arg %r does not match %s" % (a,t)
            return f(*args, **kwds)
        new_f.func_name = f.func_name
        return new_f
    return check_accepts

def returns(rtype):
    def check_returns(f):
        def new_f(*args, **kwds):
            result = f(*args, **kwds)
            assert isinstance(result, rtype), \
                   "return value %r does not match %s" % (result,rtype)
            return result
        new_f.func_name = f.func_name
        return new_f
    return check_returns


Por otro simplemente los usas. Por ejemplo una funcion "func", que recibe un 
entero y como segundo parametro un entero o un float.

@accepts(int, (int,float))
@returns((int,float))
def func(arg1, arg2):
    return arg1 * arg2
  

Y luego, solo tienes que invocar a la   funcion, los decoradores se encargan 
de comprobar que los tipos son los correctos.

>>> func(3,3)
9
>>> func(3,"hola")
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "deco.py", line 7, in new_f
    assert isinstance(a, t), \
AssertionError: arg 'hola' does not match (<type 'int'>, <type 'float'>)
>>>       

Simplemente impiden que se ejecute la funcion si los parametros no son los 
apropiados.

Si estas usando una version anterior de python, tambien se puede hacer sin 
usar decoradores, al estilo de las funciones "staticmethod" o "classmethod", 
si te interesa me lo dices y te dejare por aqui como hacerlo.

Un saludo
Joaquin


El Lunes, 23 de Mayo de 2005 16:57, Ricardo Catalinas Jimenez escribió:
> Vengo de saber programar C, y con la costumbre de hacer programas
> robustos, me gustatia saber como puedo comprobar a que clase pertenece
> el parametro con el que se llama a una funcion desde el principio.
>
> Cuando me refiero a clase, me refiero a las clases fundamentales de
> python como: int, long, string ...
>
> Digo esto porque si he entendido bien hasta donde he leido bastaria con
> esto:
>
> --- codigo ---
> class mi_clase:
> 	def funcion():
> 		pass
>
> variable = mi_clase()
> variable.funcion()
> --- codigo ---
>
> De este modo, cada vez que un objeto haga uso del metodo `funcion', este
> objeto deberia pertenecer forzosamente a `mi_clase'.
>
> Por otro lado lo que me intriga es como hacer esta comprobacion pero con
> las clases fundamentales de python, las cuales comente antes.
>
> Un saludo.
___________________________________________________
Yahoo! Messenger - Nueva versión GRATIS
Super Webcam, voz, caritas animadas, y más...
http://messenger.yahoo.es




Más información sobre la lista de distribución Python-es