How to tell which subclass was used to instantiate object

Yermat loic at fejoz.net
Mon May 3 03:00:29 EDT 2004


Frank Millman wrote:
> Hi all
> 
> I have a question regarding inheritance. I have come up with a
> solution, but it is not very elegant - I am sure there is a more
> pythonic approach. Assume the following class definitions.
> 
> class Table:
>     def __init__(self,table_name,table_type):
> 
> class Master(Table):
>     def __init__(self,table_name,table_type):
>         Table.__init__(self,table_name,table_type)
> 
> class Transaction(Table):
>     def __init__(self,table_name,table_type):
>         Table.__init__(self,table_name,table_type)
> 
> class Armaster(Master):
>     def __init__(self,table_name,table_type):
>         Master.__init__(self,table_name,table_type)
> 
>[...]
> 
> By inheriting from the incorrect class, the special methods to handle
> a 'Master' type table have been bypassed. My question is, how can
> Table check that objects have inherited from the correct subclasses?
> 
> Here is my inelegant solution. Assume that table_type contains the
> string 'Master'.
> 
> class Master(Table):
>     def __init__(self,table_name,table_type):
>         self.my_type = 'Master'
>         Table.__init__(self,table_name,table_type)
> 
> class Table:
>     def __init__(self,table_name,table_type):
>         if hasattr(self,'my_type'):
>             ok = (self.my_type == table_type)
>         else:
>             ok = False
>         if not ok:
>             raise RuntimeError('%s must be of type %s' %
>                (table_name,table_type))
> 
> Is there a more direct way for a top-level class to determine which
> subclasses were used to instantiate it?

If you are using new-style class, you should look at mro 
(http://www.python.org/2.3/mro.html). It will give you a linearization 
of the inheritance tree and thus check that object are inheriting good 
class...

 >>> class Table(object):
...     def __init__(self, table_name, table_type):
...             pass
...
 >>> class Master(Table):
...     def __init__(self, table_name, table_type):
...             super(Master, self).__init__(table_name, table_type)
...
 >>> class Transaction(Table):
...     def __init__(self, table_name, table_type):
...             super(Transaction, self).__init__(table_name, table_type)
...
 >>> class Armaster(Master):
...     def __init__(self, table_name, table_type):
...             super(Armaster, self).__init__(table_name, table_type)
...
 >>> Armaster.mro()
[<class '__main__.Armaster'>, <class '__main__.Master'>, <class 
'__main__.Table'>, <type 'object'>]
 >>> Master.mro()
[<class '__main__.Master'>, <class '__main__.Table'>, <type 'object'>]
 >>> Transaction.mro()
[<class '__main__.Transaction'>, <class '__main__.Table'>, <type object'>]

-- 
Yermat




More information about the Python-list mailing list