1

I was wandering if you have any suggestions on how I should perform the following task in python: Suppose I have the following classes:

class A(object): 
    self._classes = []
    def magic(self):
        c.foo() for c in self._classes

class B(object):
    def foo():'''some cool stuff here'''

class C(B):
    def foo():'''very cool stuff'''

class D(B):
    def foo():'''very cool stuff'''

What I want to do is when class A is instantiated all classes of type B - (C and D) will be insantiated in self._classes, meaning _classes is [C(),D()].

The general motivation for this, is that I want the user to easily add classes without the need to know about class that uses them. Any help will be appricated.

rig
  • 105
  • 5
  • Why not just instantiate an instance of C & D in the __init__ method of A ? I am guessing that the question is more complex than that. – Tony Suffolk 66 Oct 03 '14 at 17:05
  • 1
    @TonySuffolk66 My guess is that there can also be `class E(B)`, `class F(B)` and `class SpamEggsAndHam(B)` – Adam Smith Oct 03 '14 at 17:06
  • The above was a toy example. Suppose the class B is subclassed by 20 classes, or more over, I have no interest in touching the A class if some new instance of a subclass of B is created. – rig Oct 03 '14 at 17:09

3 Answers3

9

Voila (thanks to this answer for all_subclasses()):

# recursively get all subclasses of a given class
def all_subclasses(cls):
    return cls.__subclasses__() + [g for s in cls.__subclasses__()
                                   for g in all_subclasses(s)]

class B(object):
    def foo(self): print '''some cool stuff here in B'''

class C(B):
    def foo(self): print '''very cool stuff in C'''

class D(B):
    def foo(self): print '''very cool stuff in D'''

class E(D):
    def foo(self): print '''very cool stuff in E'''

class A(object):
    def __init__(self):
        self._classes = [cls() for cls in all_subclasses(B)]

    def magic(self):
        for c in self._classes: c.foo()

# usage:
A().magic()

Output:

very cool stuff in C
very cool stuff in D
very cool stuff in E
Community
  • 1
  • 1
Claudiu
  • 224,032
  • 165
  • 485
  • 680
2

If you know the module in question for example modulex, you can use dir(modulex) to list all the names in the module and then for each name x you can use modulex.__dict__.get(x) to get the actual object.
Then just check if it is of type of B.

Itay Karo
  • 17,924
  • 4
  • 40
  • 58
0

In python you can store objects like other methods in list , so first note that you need to define other class then store them in a list , also you need to using self as your foo functions argument! if you haven't subclasses you can use this :

class B(object):
    def foo(self):
        print 'B'

class C(B):
    def foo(self):
        print 'C'

class D(B):
    def foo(self):
        print 'D'

class A(object):

    def __init__(self): 
     self._classes = [B(),C(),D()]
    def magic(self):
        for c in self._classes:
            c.foo() 

A().magic()

resoult:

B
C
D
Mazdak
  • 105,000
  • 18
  • 159
  • 188