本问题已经有最佳答案,请猛点这里访问。
我有一个对象myobject,它可能返回None。如果返回None,则不会返回属性id:
a = myobject.id
因此,当myObject为None时,上面的stament会产生AttributeError:
AttributeError: 'NoneType' object has no attribute 'id'
如果myobject不是,那么我希望a等于None。如何在一行语句中避免此异常,例如:
a = default(myobject.id, None)
您应该使用getattr包装器,而不是直接检索id的值。
a = getattr(myobject, 'id', None)
这就像是说"我想从对象myobject中检索属性id,但是如果对象myobject中没有属性id,那么返回None",但是它是有效的。
有些对象还支持以下形式的getattr访问:
a = myobject.getattr('id', None)
根据操作要求,"Deep GetAttr":
def deepgetattr(obj, attr):
"""Recurses through an attribute chain to get the ultimate value."""
return reduce(getattr, attr.split('.'), obj)
# usage:
print deepgetattr(universe, 'galaxy.solarsystem.planet.name')
简单说明:
reduce就像一个就地递归函数。在这种情况下,它的作用是从EDOCX1(universe)开始,然后使用getattr递归地加深您试图访问的每个属性,因此在您的问题中,它是这样的:
a = getattr(getattr(myobject, 'id', None), 'number', None)
+这可能是最好的主意,不知道为什么我没有想到。
哈,谢谢,用你的代言无耻地自我推销。P
@如果我想以同样的方式获得属性的属性,比如a = myobject.id.number,那该怎么办?
@我的答案中增加了alwbtc。
GetAttr(myObject.id,"数字",none)怎么样?
最简单的方法是使用三元运算符:
a = myobject.id if myobject is not None else None
如果中间值为真,则三元运算符返回第一个表达式,否则返回后一个表达式。
请注意,您也可以用另一种方式进行此操作,使用异常:
try:
a = myobject.id
except AttributeError:
a = None
这符合Python的理想,即请求宽恕比许可更容易——什么是最好的将取决于情况。
评估速度快吗?我有30000件物品要做这个检查。
@ALWBTC试试看。查看timeit模块。如果您认为很大一部分值很可能是None,那么第一种方法可能更快,否则使用第二种方法。
好吧,没有值不多。所以我将使用第二种方法。但我也希望代码由一行代码组成。你不觉得一句话更好吗?
@不,可读代码更好。
@alwbtc某个东西在一条线上意味着什么都没有,事实上,这通常是一个坏迹象,因为大多数东西太复杂了,无法推到一条线上。追求可读性,然后追求性能,最后追求简洁。
@Alwbtc我的答案提供了一个一行,可读、高效,并得到了Lattyware的认可…P:看一看。
在我的对象类中,可以放置重写
class Foo(object):
def __getattribute__(self, name):
if not name in self;
return None;
else:
# Default behaviour
return object.__getattribute__(self, name)
Help on built-in function getattr in module builtins:
getattr(...)
getattr(object, name[, default]) -> value
Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
When a default argument is given, it is returned when the attribute doesn't
exist; without it, an exception is raised in that case.
以下内容应该有效:
a = getattr(myobject, 'id', None)
如果你想解决myobject类定义中的问题(如黑钻石的答案),你可以简单地定义__getattr__返回None:
class Myobject:
def __getattr__(self, name):
return None
这是因为只有在尝试访问不存在的属性时才调用__getattr__,而不管属性的名称如何,总是首先调用__getattribute__。(另请参见本帖。)
尝试:
myobject = Myobject()
print myobject.id
myobject.id = 7
print myobject.id
a=myobect.id if myobject else None
try:
a = myobject.id
except AttributeError:
a = None
也会起作用,而且更清楚,IMO
我不是Python专家,但在我以前处理过的大多数语言中,"except"语句中的内容有一个额外的开销,这是不重要的。在这种简单的情况下,我建议您使用"getattr"方法(假设这样做的成本更低)。你们中的一些人能说说getattr方法吗?
过早优化、良好的LAD、过早优化
这不是过早的优化。使用异常处理正常行为通常被认为是不好的风格。
python的异常没有那么昂贵,这就是它在解释器源代码中显示的方式。