Reputation: 4845
I've got a problem which is a bit difficult to explain. I have a module which consists of more than one class: someModule.py
#imports over here
class Default(Base):
def __init__(self):
a = Rectangle() #all these guys derive from Shape
b = Circle()
c = Sphere()
class Foo:
#members over here
#other classes/functions/whatever we can define here, except the boiler plate code to check __main__
What i want to do is create an object of the class which derives from a specific base class (eg. Base) at run time and manipulate those data members which derive from another specific base class (eg. Shape). Meaning i want to write such a script that takes module name and performs the above task. Any ideas how i can do this using inspect or something else? I've taken a look at inspect but didn't quite find the methods that should get the job done. I may be missing something.
Upvotes: 3
Views: 149
Reputation: 29302
There is no way to know what's inside __init__
before the creation of the instance.
You can only check them after, and one way to do it is with vars()
:
defy = Default()
for name,value in vars(defy).items():
if isinstance(value, Shape):
# manipulate
To do the above on all the classes in someModule.py that are also subclasses of Base
:
import someModule
instances = []
for cls_name,cls in vars(someModule):
if issubclass(cls, Base):
obj = cls()
for name,value in vars(cls).items():
if isinstance(value, Shape):
# manipulate
instances.append(obj)
Instead, if you want to manipulate which Shape
subclass is going to be instanciated, you'll have to make them class attributes, example:
class Default(Base):
default_shapes = [Rectangle, Circle, Sphere]
def __init__(self):
self.shapes = [shape() for shape in self.__class__.default_shapes]
Upvotes: 1
Reputation: 70552
Here's one way: make sure that your base classes (e.g. Base, Shape) are new-style classes (they inherit from object
). By doing so, you can use the built-in __subclasses__()
function to get a list of all derived classes. Then you can simply create an object and go through the fields, comparing them with the classes that you're interested in.
baseDerived = Base.__subclasses__()
shapeDerived = Shape.__subclasses__()
# Iterate through derived classes
for derivedClass in baseDerived:
derivedObject = derivedClass()
# Iterate through data attributes
for attr, dataMember in derivedObject.__dict__.iteritems():
if dataMember.__class__ in shapeDerived:
# Do stuff with the data member here
Upvotes: 0