In a Python object, how can I see a list of properties that have been defined with the @property decorator?
Question:
I can see first-class member variables using self.__dict__
, but I’d like also to see a dictionary of properties, as defined with the @property decorator. How can I do this?
Answers:
dir(obj)
gives a list of all attributes of obj
, including methods and attributes.
The properties are part of the class, not the instance. So you need to look at self.__class__.__dict__
or equivalently vars(type(self))
So the properties would be
[k for k, v in vars(type(self)).items() if isinstance(v, property)]
You could add a function to your class that looks something like this:
def properties(self):
# class_items = self.__class__.__dict__.iteritems() # Python 2
class_items = self.__class__.__dict__.items()
return dict((k, getattr(self, k))
for k, v in class_items
if isinstance(v, property))
This looks for any properties in the class and then creates a dictionary with an entry for each property with the current instance’s value.
For an object f, this gives the list of members that are properties:
[n for n in dir(f) if isinstance(getattr(f.__class__, n), property)]
As user2357112-supports-monica points out in a comment to a duplicate question, the accepted answer only gets those properties directly defined on the class, missing inherited properties. In order to fix this, we also need to walk over the parent classes:
from typing import List
def own_properties(cls: type) -> List[str]:
return [
key
for key, value in cls.__dict__.items()
if isinstance(value, property)
]
def properties(cls: type) -> List[str]:
props = []
for kls in cls.mro():
props += own_properties(kls)
return props
For example:
class GrandparentClass:
@property
def grandparent_prop(self):
return "grandparent_prop"
class ParentClass(GrandparentClass):
@property
def parent_prop(self):
return "parent"
class ChildClass(ParentClass):
@property
def child_prop(self):
return "child"
properties(ChildClass) # ['child_prop', 'parent_prop', 'grandparent_prop']
If you need to get the properties of an instance, simply pass instance.__class__
to get_properties
I can see first-class member variables using self.__dict__
, but I’d like also to see a dictionary of properties, as defined with the @property decorator. How can I do this?
dir(obj)
gives a list of all attributes of obj
, including methods and attributes.
The properties are part of the class, not the instance. So you need to look at self.__class__.__dict__
or equivalently vars(type(self))
So the properties would be
[k for k, v in vars(type(self)).items() if isinstance(v, property)]
You could add a function to your class that looks something like this:
def properties(self):
# class_items = self.__class__.__dict__.iteritems() # Python 2
class_items = self.__class__.__dict__.items()
return dict((k, getattr(self, k))
for k, v in class_items
if isinstance(v, property))
This looks for any properties in the class and then creates a dictionary with an entry for each property with the current instance’s value.
For an object f, this gives the list of members that are properties:
[n for n in dir(f) if isinstance(getattr(f.__class__, n), property)]
As user2357112-supports-monica points out in a comment to a duplicate question, the accepted answer only gets those properties directly defined on the class, missing inherited properties. In order to fix this, we also need to walk over the parent classes:
from typing import List
def own_properties(cls: type) -> List[str]:
return [
key
for key, value in cls.__dict__.items()
if isinstance(value, property)
]
def properties(cls: type) -> List[str]:
props = []
for kls in cls.mro():
props += own_properties(kls)
return props
For example:
class GrandparentClass:
@property
def grandparent_prop(self):
return "grandparent_prop"
class ParentClass(GrandparentClass):
@property
def parent_prop(self):
return "parent"
class ChildClass(ParentClass):
@property
def child_prop(self):
return "child"
properties(ChildClass) # ['child_prop', 'parent_prop', 'grandparent_prop']
If you need to get the properties of an instance, simply pass instance.__class__
to get_properties