Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine if given class attribute is a property or not, Python object

Tags:

python

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.

like image 217
ScotchAndSoda Avatar asked Jul 18 '13 23:07

ScotchAndSoda


People also ask

How do you check if an object has a property in Python?

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.

How do you find the attributes of an object in Python?

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.

Is class an attribute or property?

Properties are special kind of attributes. Two types of attributes: Class attribute.

Is class an attribute or object?

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.


2 Answers

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 
like image 124
John La Rooy Avatar answered Oct 11 '22 18:10

John La Rooy


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.

like image 39
kindall Avatar answered Oct 11 '22 16:10

kindall