Reputation: 353
Here is my sample code to check if the given attribute is present in the class or not.
class EmpDict:
def __init__(self, data):
self.data = data
try:
self.first_name = data['first_name']
self.age = data['age']
self.last_name = data['last_month']
except:
pass
def is_attr_available(self, attr):
try:
hasattr(EmpDict, attr)
return True
except:
return False
Here is the test:
>> emp = {'first_name' : 'Tom', 'last_name' : 'Jose'}
>> a = EmpDict(emp)
>> print(a.is_attr_available(a.first_name))
True
>> print(a.is_attr_available(a.age))
print(a.is_attr_available(a.age))
AttributeError: 'EmpDict' object has no attribute 'age'
I expected False for the last statement, instead I get an AttributeError even though I also captured the exception in is_attribute_available method.
Any leads on what I am doing wrong here?
Upvotes: 3
Views: 2562
Reputation: 71610
Agree with @blhsing, but I changed your code around a little bit,(there are some little things that can be better) one thing is that the second argument of hasattr
should be a string not a attribute,
Example:
class EmpDict:
def __init__(self, data):
self.data = data
try:
self.first_name = data['first_name']
self.age = data['age']
self.last_name = data['last_month']
except:
()
def is_attr_available(self, attr):
return hasattr(self,attr)
emp = {'first_name' : 'Tom', 'last_name' : 'Jose'}
a = EmpDict(emp)
print(a.is_attr_available('age'))
Output:
False
Also:
You don't need an try-except
for hasattr
(otherwise why is it called hasattr
)
From the documentation:
hasattr(object, name)
The arguments are an object and a string. The result is True if the string is the name of one of the object’s attributes, False if not. (This is implemented by calling getattr(object, name) and seeing whether it raises an exception or not.)
Here is a much better code for it:
class EmpDict:
def __init__(self, data):
self.data = data
self.first_name = data.get('first_name')
self.age = data.get('age')
self.last_name = data.get('last_month')
def is_attr_available(self, attr):
return hasattr(self, attr) and getattr(self,attr)!=None
emp = {'first_name' : 'Tom', 'last_name' : 'Jose'}
a = EmpDict(emp)
print(a.is_attr_available('age'))
Upvotes: 1
Reputation: 366103
That's not how you use hasattr
.
First, you use hasattr
when you have the attribute name as a string value:
attrname = 'age'
hasattr(a, attrname)
You can't pass it a.age
—that's already trying to look up a.age
, and then pass the result of that as the attribute name. That will be false if there is an age (because you don't have an attribute named 23
), and it won't even get to hasattr
if there isn't one.
But there are two other problems with your code.
First, hasattr
returns True if the attribute is there, False
if it isn't. It only raises an exception if there's a typo in your code or a serious bug in your class (and you don't want an except:
to catch those and just make the problem impossible to debug).
Second, EmpDict
is the class. The class doesn't have any of these attributes, so that's always going to return false. You want to know if the instance, self
, has them.
So:
def is_attr_available(self, attr):
return hasattr(self, attr)
And then, you could change your code to call
print(a.is_attr_available('age'))
But really, why do you even want this function? Why not just:
try:
the a.age
?None
so the attribute always exists?Upvotes: 3
Reputation: 107115
hasattr
takes the attribute name as a string as the second argument, so you should pass to it the name of the attribute instead:
print(a.is_attr_available('age'))
Otherwise you would raise the AttributeError
exception by trying to evaluate a.age
.
Also, hasattr
does not raise any exception, but simply returns True if the object has the attribute, so you should modify your is_attr_available
function to:
def is_attr_available(self, attr):
return hasattr(self, attr)
Upvotes: 1