我试图只在属性存在的情况下获取列表中类的属性值。如果属性不存在,我希望它获取其他内容(我知道它是内部列表,并且希望在该内部列表中获取项的属性)。你知道吗
下面代码中的示例,可以运行和调试:
class Block(object):
def __init__(self, name):
self.block_name = name
blocks_list = [Block("d"), Block("d"), Block("d")]
blocks = [Block("a"), Block("b"), blocks_list, Block("c")]
# this is ok
block_num = 2
name = getattr(blocks[block_num], 'block_name', blocks[block_num][0].block_name)
# this is raises exception
block_num = 0
name = getattr(blocks[block_num], 'block_name', blocks[block_num][0].block_name)
例外情况:
name = getattr(blocks[block_num], 'block_name', blocks[block_num][0].block_name) TypeError: 'Block' object does not support indexing
我不明白为什么getattr在第三个argumnet上引发异常,而它不应该引发异常。你知道吗
我的最终目标是确定列表或内部列表中所有项目的名称。你知道吗
谢谢。你知道吗
您的第一个case在
block_num = 2
,blocks[2][0]
是<__main__.Block at 0x....>
时起作用,因为blocks[2]
是一个列表在第一种情况下,您有
getattr(blocks[block_num], 'block_name', blocks[block_num][0].block_name)
表示block_num = 2
,blocks[block_num]
是一个列表,并且该列表不包含block_name
,因此返回默认值blocks[block_num][0].block_name
在第二种情况下,对于
block_num=0
,在调用函数时会计算默认值,但最终会抛出TypeError: 'Block' object is not subscriptable
,因为blocks[0]
是一个对象<__main__.Block at 0x....>
,并且不能索引对象为了保持一致,一个建议可能是改为
blocks_list[block_num].block_name
更新后的代码可能看起来像
这给了你
我想您理解为什么在您的第二个示例中,第三个参数会引发错误—这是因为
blocks[0]
不是一个列表,所以您不能索引到它。我还认为您希望不会出现错误,因为只有当blocks[0]
没有属性'block_name'
(因为getattr()
的第三个参数是默认值)时,才应该计算第三个参数。你知道吗不幸的是,它不是这样工作的。您给出的第三个参数
getattr()
(即blocks[block_num][0]
)是在调用函数时计算的,而不是在执行函数时计算的。你知道吗不过,有一个解决方法:三元运算符可以做与
getattr()
相同的事情(如果存在,则返回一个属性,如果不存在,则返回一个默认值),但是在执行时而不是在调用时计算其他参数:在对
getattr()
的调用中,在执行函数之前,这三个参数将同时求值。在我给出的这个表达式中,它们的求值顺序如下:if hasattr(blocks[block_num], 'block_name')
blocks[block_num].block_name
(如果1为真)blocks[block_num][0].block_name
(如果1为假)这应该能解决你的问题。你知道吗
相关问题 更多 >
编程相关推荐