[Python-es] problema con __init__() en clase heredada, entre otras cosas, de threading.Thread

Anler Hernandez Peral anler86 en gmail.com
Mar Dic 13 02:29:53 CET 2011


Hola Jose

El problema está en que al crear una instancia de tu clase:

instance = MyClass_1('x', 'y')

se están ejecutando los métodos __init__ de cada clase de la jerarquía en
un cierto orden (esto se llama method resolution order o mro), dicho orden
lo puedes ver para MyClass_1 de la siguiente forma:

MyClass_1.mro()

lo cual a mi me da como resultado:

[<class '__main__.MyClass_1'>, <class 'threading.Thread'>, <class
'threading._Verbose'>, <class '__main__.Local_Interface_1'>, <class
'__main__.Global_Interface'>, <type 'object'>]


que significa esto? que el primer __init__ que se buscara será el de
MyClass_1, y luego el threading.Thread, etc, entonces, al no tener __init__
MyClass_1, se invoca el de threading.Thread pasandole los argumentos 'x',
'y' que pasamos al crear nuestra instancia y justamente aqui es donde falla
porque Thread se queja sobre el primer parametro de posicion que debe ser
None

Solucion: simplemente debes definir correctamente tu herencia para que se
ejecuten las inicializaciones en el orden que desees:

cambia

class MyClass_1(threading.Thread, Local_Interface_1):

por

class MyClass_1(Local_Interface_1, threading.Thread):

de esta forma el mro quedara asi:

[<class '__main__.MyClass_1'>, <class '__main__.Local_Interface_1'>, <class
'__main__.Global_Interface'>, <class 'threading.Thread'>, <class
'threading._Verbose'>, <type 'object'>]


--
anler


2011/12/13 Jose Caballero <jcaballero.hep en gmail.com>

> Hola,
>
>
>
> por una seria de razones (llamémosle exigencias del guión"), tenga una
> jerarquía de clases heredadas unas de otras.
> Una version simplificada del código es [1].
>
> -- Necesito que la clase con la que voy a trabajar, MyClass_1, sea un
> "singleton" y a la vez un "thread".
>
> -- Al mismo tiempo esa clase debe tener una interfaz que se define en
> Local_Interface_1
>
> -- Y es importante que se sepa si los objetos de esa clase son creados de
> forma adecuada o no.
> Para asegurarme de ello, he intentado que la clase "madre de todas las
> clases", Globa_Interface,
> obligue a la implementación de un método initialize() y en su __init__()
> se comprueba si un atributo self.valid es True o False.
>
>
> Obtengo este error [2].
> Por lo que he podido "debuggear" parece ser que con esta jerarquía de
> clases la línea threading.Thread.__init__(self) nunca llega a ejecutarse.
> ¿Alguna idea de la razón?
>
>
>
> Muchas gracias por adelantado. Cualquier comentario será bienvenido.
> Jose
>
>
> =====================================================
> [1]
>
> class Singleton(type):
>     def __init__(cls, name, bases, dct):
>         cls.__instance = None
>         type.__init__(cls, name, bases, dct)
>     def __call__(cls, *args, **kw):
>         if cls.__instance is None:
>             cls.__instance = type.__call__(cls, *args,**kw)
>         return cls.__instance
>
>
> ---------------------------------------------------------------------------------------------------
>
> class Global_Interface(object):
>     def __init__(self, *k, **kw):
>         self.valid = True
>         try:
>             self.initialize(*k, **kw)
>         except:
>             self.valid = False
>
>     def initialize(self, *k, **kw):
>         raise NotImplementedError
>
>
> ---------------------------------------------------------------------------------------------------
>
> class Local_Interface_1(Global_Interface):
>     def f(self):
>         raise NotImplementedError
>
>
> class Local_Interface_2(Global_Interface):
>     def g(self):
>         raise NotImplementedError
>
>
> ---------------------------------------------------------------------------------------------------
>
> class MyClass_1(threading.Thread, Local_Interface_1):
>     __metaclass__ = Singleton
>     def initialize(self, x, y):
>         threading.Thread.__init__(self)
>         self.x = x
>         self.y = y
>
>         ... otras operaciones de inicializacion...
>
>         self.valid = True
>
>     def f(self):
>     ... blah blah ...
>
>
> =====================================================
> [2]
>
>  File "/usr/lib64/python2.4/threading.py", line 378, in __init__
>    assert group is None, "group argument must be None for now"
> AssertionError: group argument must be None for now
>
>
> _______________________________________________
> Python-es mailing list
> Python-es en python.org
> http://mail.python.org/mailman/listinfo/python-es
> FAQ: http://python-es-faq.wikidot.com/
>
>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://mail.python.org/pipermail/python-es/attachments/20111213/24d7c122/attachment.html>


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