Savir
Savir

Reputation: 18418

Get only properties of an instance

I was wondering if there's a way in Python(2.6) to get only the name of the properties an instance has.

Let's say I have:

#!/usr/bin/python2.6

class MyClass(object):
    def __init__(self):   
        self._x = None

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, value):
        print "Setting x to %s" % (value)
        try:
            self._x = int(value)
        except ValueError:
            self._x = None



#main (test area)
if __name__ == '__main__':
    a = MyClass()
    a.x = "5"
    print str(a.x)
    print "Vars: %s" %vars(a)   
    print "Dir: %s" %dir(a)

Which outputs:

Vars: {'_x': 5}
Dir: ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_x', 'x']

Is there a similar command to "vars" or "dir" or so that would give me "x" only?

If not, what do you guys recommend to do? Walk the "vars" keys and remove the "_" that appears in front of "_x"?

Thank you in advance!

Upvotes: 0

Views: 1804

Answers (3)

Sylvain Defresne
Sylvain Defresne

Reputation: 44463

You can use the following code:

def iter_properties_of_class(cls):
    for varname in vars(cls):
        value = getattr(cls, varname)
        if isinstance(value, property):
            yield varname

def properties(inst):
    result = {}
    for cls in inst.__class__.mro():
        for varname in iter_properties_of_class(cls):
            result[varname] = getattr(inst, varname)
    return result

>>> a = MyClass()
>>> a.x = 5
Setting x to 5
>>> properties(a)
{'x': 5}

Upvotes: 5

kevpie
kevpie

Reputation: 26088

Just adding to what @nosklo's posted, for his quickness.

Descriptors are how properties are implemented.

>>> o = MyClass()
>>> print type(o.x)
<type 'NoneType'>
>>> print type(MyClass.x)
<type 'property'>

Upvotes: 1

nosklo
nosklo

Reputation: 222802

Instances don't have properties. They are descriptors, so they have to be in the class to work. vars(MyClass) should return it.

class MyClass(object):
    @property
    def x(self):
        pass

print vars(MyClass).keys()

prints

['__module__', '__dict__', 'x', '__weakref__', '__doc__']

Upvotes: 1

Related Questions