10ok
10ok

Reputation: 41

How to get a list of instance attributes

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

Answers (2)

sameera sy
sameera sy

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

Martijn Pieters
Martijn Pieters

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

Related Questions