Reputation: 33628
Please see the following example code, which is in a file, say
classattr.py
class BaseClass(object):
def __init__(self, param1, param2):
self.param1 = param1
self.param2 = param2
def somemethod(self):
return "This is returned when I do Base.__dict__"
class ChildOfBaseClass(BaseClass):
def __init__(self, param1, param2, param3, param4):
super(ChildOfBaseClass, self).__init__(param1, param2)
self.param3 = param3
self.param4 = param4
def somemethod(self, param3, param4):
a = param3 + param4
return a
I want to get all the attributes (I am assuming that param1
, param2
etc. are called attributes) of the classes before I create any instance. Command dir(classattr.BaseClass)
does not list param1
and param2
. It, however, does return the method somemethod
.
I am trying to get the attributes for the following reason: The module classattr
is imported in another file where the name of the class, either classattr.BaseClass
or classattr.ChildOfBaseClass
is provided as an input to some function. I want to determine which one it is during the runtime and then use appropriate inputs (either param1
and param2
if the former, or all the parameters param1
to param4
if the latter) when creating the instance. The way I was thinking of doing this is to check whether the class has param3
as an attribute and then creating the instance with correct inputs. Is there another better way to check? Another way is to have param3
and param4
as inputs in BaseClass
even if they do not do anything and then always create instance with all four parameters as inputs. But that does not seems appropriate way of doing things.
Thank you.
Upvotes: 0
Views: 1908
Reputation: 184181
There's no real way to get the names of attributes that are only assigned after the object is created, such as those defined in __init__()
, without actually creating the instance. The __init__()
method can do anything at all, and an instance might have been even further amended by code that's not even in the class. So if you want to know what attributes an instance has, you need an instance.
Upvotes: 2
Reputation: 71450
BrenBarn's answer directs you to some ideas that might help you solve your problem. I just thought I'd add some notes on terminology.
In Python, the attributes of an object are the named values stored within it (and an object is pretty much nothing more and nothing less than "a thing that has attributes"). They are retrieved with the dotted.name
syntax.
Classes in Python are objects. They therefore have attributes. The most important ones are all the names that you defined in the class
block (including the methods), which become attributes of the class object. So when you ask about the attributes of a class, it sounds like you're wanting to retrieve the attributes of the class object itself, which is not actually the case.
Indeed one of the things dir(classattr.BaseClass)
is doing is looking up the attributes of classattr.BaseClass
, where it finds the somemethod
attribute, but does not find param1
or param2
because they are not attributes of the class object BaseClass
; they (will be) attributes of instances of BaseClass
once those instances have been created and initialised.
But what you really seem to be asking about is how to find out the call signature of the __init__
method of a given class. As noted by BrenBarn, although classes are often written to simply directly initialise their instances' attributes from the arguments to __init__
, there is absolutely no guarantee that this is the case. But if your purpose is just to know what information to pass to a class in order to create an instance, then you don't need to know (and shouldn't care) what will end up being stored as attributes, but rather just what are the required parameters to the __init__
method.
Upvotes: 1
Reputation: 251383
You can't know what instance attributes a class will give to its instances, because they don't exist before an instance is created.
However, if what you want is to know what parameters you need to pass when instantiating the class, you can inspect the call signature of the class's __init__
method to see what parameters it accepts. See Determining the number of parameters in a lambda for some information about getting the call signature.
Note that there's no inherent relationship between instance attributes and __init__
parameters. You could have a class like this:
class Foo(object):
def __init__(self):
self.someAttr = 10
. . . which defines an instance attribute without receiving any parameters. (Or vice versa, a class that accepts parameters but doesn't use them to create instance attributes.)
Upvotes: 2