即使捕获了异常,hasattr也会返回属性错误

时间:2018-08-11 02:47:04

标签: python

这是我的示例代码,用于检查给定属性是否存在于类中。

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

这是测试:

>> 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'

我希望最后一条语句为False,即使我也用is_attribute_available方法捕获了异常,但我得到AttributeError。

有人在说我在做什么错吗?

3 个答案:

答案 0 :(得分:2)

这不是您使用Fixpoint beqnat(n m : nat): bool:= match n with |0=> match m with |0=> true |S m' => false end |S n'=> match m with |0=>false |S m'=> beqnat n' m' end end. Theorem beq sys: forall(n m:nat), beqnat n m = beqnat m n. 的方式。

首先,将属性名称作为字符串值使用hasattr

hasattr

您无法传递它attrname = 'age' hasattr(a, attrname) -已经在尝试查找a.age,然后将其结果作为属性名称传递。如果有年龄,那将是错误的(因为您没有名为a.age的属性),如果没有年龄,甚至都不会到达23


但是您的代码还有另外两个问题。

首先,如果属性存在,hasattr返回True,否则返回hasattr。只有在您的代码中有错别字或类中存在严重的错误时,它才会引发异常(并且您不希望False捕获到这些错误并且只是使问题无法调试)。

第二,except:是课程。该类没有这些属性,因此总是会返回false。您想知道实例 EmpDict是否具有它们。

所以:

self

然后,您可以将代码更改为调用

def is_attr_available(self, attr):
    return hasattr(self, attr)

但是,实际上,为什么还要使用此功能?为什么不只是:

  • print(a.is_attr_available('age')) try:
  • …或提供诸如a.age之类的默认值,以便该属性始终存在?

答案 1 :(得分:1)

hasattr将属性名称作为字符串作为第二个参数,因此您应该将属性名称传递给它:

print(a.is_attr_available('age'))

否则,您将通过尝试评估AttributeError来引发a.age异常。

此外,hasattr不会引发任何异常,但是如果对象具有属性,则仅返回True,因此您应该将is_attr_available函数修改为:

def is_attr_available(self, attr):
    return hasattr(self, attr)

答案 2 :(得分:1)

同意@blhsing,但我对您的代码做了一些改动((有些小事情可能会更好)。一件事是hasattr的第二个参数应该是字符串而不是属性,

示例:

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')) 

输出:

False

也:

您不需要try-except的{​​{1}}(否则为什么叫hasattr

从文档中:

  

hasattr(对象,名称)

     
    

参数是一个对象和一个字符串。如果字符串是对象属性之一的名称,则结果为True,否则为False。 (这是通过调用getattr(object,name)并查看它是否引发异常来实现的。)

  

这是一个更好的代码:

hasattr