instantiate all subclasses of a class

D

Daniel Nogradi

What is the simplest way to instantiate all classes that are
subclasses of a given class in a module?

More precisely I have a module m with some content:

# m.py
class A:
pass
class x( A ):
pass
class y( A ):
pass
# all kinds of other objects follow
# end of m.py

and then in another module I have currently:

# n.py
import m
x = m.x( )
y = m.y( )
# end of n.py

and would like to automate this in a way that results in having
instances of classes from m in n whose names are the same as the
classes themselves. But I only would like to do this with classes that
are subclasses of A.

Any ideas?
 
M

Marc 'BlackJack' Rintsch

Daniel Nogradi said:
More precisely I have a module m with some content:

# m.py
class A:
pass
class x( A ):
pass
class y( A ):
pass
# all kinds of other objects follow
# end of m.py

and then in another module I have currently:

# n.py
import m
x = m.x( )
y = m.y( )
# end of n.py

and would like to automate this in a way that results in having
instances of classes from m in n whose names are the same as the
classes themselves. But I only would like to do this with classes that
are subclasses of A.

Any ideas?

Just go through the objects in the module, test if they are classes,
subclasses of `A` and not `A` itself:

from inspect import isclass
import test

instances = dict()
for name in dir(test):
obj = getattr(test, name)
if isclass(obj) and issubclass(obj, test.A) and obj is not test.A:
instances[name] = obj()
 
S

Simon Forman

Daniel said:
What is the simplest way to instantiate all classes that are
subclasses of a given class in a module?

More precisely I have a module m with some content:

# m.py
class A:
pass
class x( A ):
pass
class y( A ):
pass
# all kinds of other objects follow
# end of m.py

and then in another module I have currently:

# n.py
import m
x = m.x( )
y = m.y( )
# end of n.py

and would like to automate this in a way that results in having
instances of classes from m in n whose names are the same as the
classes themselves. But I only would like to do this with classes that
are subclasses of A.

Any ideas?

It's pretty easy


import m
from inspect import getmembers, isclass, getmro

t = '%s = m.%s()'

for name, class_ in getmembers(m, isclass):
if class_ is m.A:
continue
if m.A in getmro(class_):
exec t % (name, name)


Peace,
~Simon
 
D

Daniel Nogradi

More precisely I have a module m with some content:
# m.py
class A:
pass
class x( A ):
pass
class y( A ):
pass
# all kinds of other objects follow
# end of m.py

and then in another module I have currently:

# n.py
import m
x = m.x( )
y = m.y( )
# end of n.py

and would like to automate this in a way that results in having
instances of classes from m in n whose names are the same as the
classes themselves. But I only would like to do this with classes that
are subclasses of A.

Any ideas?

Just go through the objects in the module, test if they are classes,
subclasses of `A` and not `A` itself:

from inspect import isclass
import test

instances = dict()
for name in dir(test):
obj = getattr(test, name)
if isclass(obj) and issubclass(obj, test.A) and obj is not test.A:
instances[name] = obj()


Thanks, this looks pretty good. However there is some wierdness with
isclass: whenever a class has a __getattr__ method an instance of it
will be detected by isclass as a class (although it is not).
.... def __getattr__( self, attr ):
.... pass
....
If there is no __getattr__ method isclass works as expected. Am I
misunderstanding something here or isclass should return False for any
instance of any class including those with a __getattr__ method?
 
P

Peter Otten

Daniel said:
Thanks, this looks pretty good. However there is some wierdness with
isclass: whenever a class has a __getattr__ method an instance of it
will be detected by isclass as a class (although it is not).

... def __getattr__( self, attr ):
... pass
...
True

Which reinforces Michael Spencer's instinct that the inspect.isclass()
implementation is a bit too clever (see
http://mail.python.org/pipermail/python-list/2006-July/351448.html).
If there is no __getattr__ method isclass works as expected. Am I
misunderstanding something here or isclass should return False for any
instance of any class including those with a __getattr__ method?

It certainly should, and I believe that the obvious test

isinstance(obj, (types.ClassType, type))

will work.

Peter
 
D

Daniel Nogradi

from inspect import isclass
Which reinforces Michael Spencer's instinct that the inspect.isclass()
implementation is a bit too clever

Wouldn't the word 'broken' be more appropriate? :)
isinstance(obj, (types.ClassType, type))

Thanks a lot this indeed works.
 
D

Daniel Nogradi

What is the simplest way to instantiate all classes that are
It's pretty easy


import m
from inspect import getmembers, isclass, getmro

t = '%s = m.%s()'

for name, class_ in getmembers(m, isclass):
if class_ is m.A:
continue
if m.A in getmro(class_):
exec t % (name, name)

Actually, this variant also suffers from the broken isclass implementation.

(Simon, sorry for the double post.)
 
S

Simon Forman

Daniel said:
Actually, this variant also suffers from the broken isclass implementation.

(Simon, sorry for the double post.)


Not a problem, I haven't used inspect much so I've not been bitten by
this bug before. It's good to know!

(I would have assumed that isclass() would have been implemented as
isinstance(obj, (types.ClassType, type)) anyway. I'm surprised it's
not, and that it's so broken..)

Thanks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,989
Messages
2,570,207
Members
46,782
Latest member
ThomasGex

Latest Threads

Top