It's all in the title. Here is the following example:
class A(object): my_var = 5 def my_method(self, drink='beer'): return 'I like %s' % drink @property def my_property(self): return 'I do not drink coffee'
I instantiate an A object and I want to know the type of each attribute and if it is a callable. For this I'm using dir()
.
obj = A() for attr in dir(obj): print 'Type: %s' % type(obj) print 'Is callable: %s' % callable(attr)
I have to know also if an attribute is a property. I'm sure that there is a way to know this. All suggestions will be appreciated.
We can use hasattr() function to find if a python object obj has a certain attribute or property. hasattr(obj, 'attribute'): The convention in python is that, if the property is likely to be there, simply call it and catch it with a try/except block.
getattr() – This function is used to access the attribute of object. hasattr() – This function is used to check if an attribute exist or not. setattr() – This function is used to set an attribute. If the attribute does not exist, then it would be created.
Properties are special kind of attributes. Two types of attributes: Class attribute.
Class attributes are the variables defined directly in the class that are shared by all objects of the class. Instance attributes are attributes or properties attached to an instance of a class. Instance attributes are defined in the constructor.
You need to look at the class (this is the case for descriptors in general), which for objects you can find via the __class__
attribute or by using the type function:
>>> obj.__class__.my_property <property object at 0xb74bd16c>
or by
>>> type(obj).my_property <property object at 0xb720b93c>
These result in the same "property object" as if you were to directly check the attribute of the class (implying you know the class' name in your code instead of checking it dynamically like you probably should rather do):
>>> A.my_property <property object at 0xb7312345>
So to test if a specific attribute of an object is a property, this would be one solution:
>>> isinstance(type(obj).my_property, property) True
I once asked a similar question. The trouble you'll run into, of course, is that you can't access the property through the instance to determine its type without calling the getter, which gets you the type of whatever the getter returns. So you have to access the property through its class rather than through the instance.
property
is already a type, so you can just compare directly to that. (I originally had some superfluous code here that got the property type out of a class that had a property. I thought this was necessary due to a typo when I was testing things.)
obj_type = type(obj) for attr in dir(obj): if isinstance(getattr(type(obj), attr, None), property): print attr, "is a property"
Don't worry about having an instance attribute with the same name. It's ignored in attribute lookup if there's a data descriptor of the same name on the class (property
is a data descriptor).
Of course, any class can be a data descriptor, not just property
, so in theory you really want to check for __get__()
and/or __set__()
and/or __delete__()
attributes on the type. But the problem with that approach is that all functions and methods are themselves descriptors and therefore would be caught by that check. It quickly becomes silly to try to find all the exceptions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With