Reputation: 41
Is there a function which will get a list of class/__init__
attributes without having a single object. I need names of class attributes to pass it into a function. I tried to search for a solution many hours but most of them require using sth like x = ClassName()
- in my case it produces an error (e.g. __init__()
takes exactly 6 arguments (1 given)).
For example:
class Car:
def __init__(self, name, year, color):
self.name = name
self.year = year
self.color = color
How do I get a list like:
list_of_attr = ['name', 'year', 'color']
Is it even possible?
Edit: Adding some context to my question - I am trying to create a function which will get data from text file and convert it to a list of objects. Each line in a file contains data for one object - in above case it would be e.g. 'Volvo,1995,blue'. I have right now two classes and two files (but expect more) and I have already created working solution but right now I have to pass names of object/instance attributes to my function in a pre-written list. I want it to be done automatically, based only on a class name.
Upvotes: 3
Views: 6273
Reputation: 1718
In short, it is not possible. You cannot get the memeber variables without having created memory for it (meaning: you have to create an object)There's an alternate approach for this, but the only thing is you need to have default values for the __init__()
method. Take a look at this
class Car:
def __init__(self, name="default", year=1995, color="red"):
self.name = name
self.year = year
self.color = color
members = [mems for mems in dir(Car()) if not callable(mems) and not mems.startswith("__")]
print members
The output
['color', 'name', 'year']
Upvotes: 3
Reputation: 1123350
There are no class attributes at all on your class. Your __init__
method sets instance attributes, so you can only access those names once you have an instance and __init__
actually has run.
At that point you can the vars()
function to get the namespace of an instance; this gives you a dictionary, so you can get the keys:
vars(x).keys()
If you were looking for what arguments the __init__
method expects, you can use inspect.getargspec()
to introspect the signature. This gives you the names of all arguments, and values for any defaults (so keyword arguments). From this you can deduce the number of required (positional) arguments:
import inspect
argspec = inspect.getargspec(Car.__init__)
required = argspec.args
if argspec.defaults:
required = required[:-len(argspec.defaults)]
This will include the self
argument passed in automatically for bound methods; you can ignore that first argument with a slice:
method_required = argspec.args[1:]
if argspec.defaults:
method_required = method_required[:-len(argspec.defaults)]
Demo:
>>> import inspect
>>> class Car:
... def __init__(self, name, year, color):
... self.name = name
... self.year = year
... self.color = color
...
>>> vars(Car('Volvo', 1975, 'blue'))
{'color': 'blue', 'name': 'Volvo', 'year': 1975}
>>> vars(Car('Volvo', 1975, 'blue')).keys()
['color', 'name', 'year']
>>> inspect.getargspec(Car.__init__)
ArgSpec(args=['self', 'name', 'year', 'color'], varargs=None, keywords=None, defaults=None)
Upvotes: 9