避免额外的行进行属性检查?

时间:2016-09-17 13:09:18

标签: python attributes

我正在开发这个Python项目,我多次遇到这种情况,我想知道是否有更好的方法。

有一个类实例列表。列表的某些部分是空的(填充None)。 这是一个示例列表。

ins_list = [ins_1, ins_2, None, ins_3, None]

我必须在整个程序流程中做一些确认。我需要控制这些实例的属性。但是只给出了从列表中选择实例的索引,它可能是空元素之一。调用属性时会出错。这是一个示例程序流程。

ind = 2

if ins_list[ind].some_attribute == "thing":
    # This would give error when empty element is selected.

我通过使用

来解决这个问题
if ins_list[ind]:
    if ins_list[ind].some_attribute == "thing":
        # This works

我可以使用它。但是程序很长,我应用了数百次。是否有更简单,更好的方法,这意味着我正在生成reduntant代码并无缘无故地增加缩进级别。我想知道是否有这样的解决方案。

4 个答案:

答案 0 :(得分:0)

有以下两种选择:

  

使用字典:

另一种方法是使用dictionary代替。因此,您可以在列表填充元素后创建字典。字典的键将是列表的值,作为值,您可以使用非None和" No_attr"的元素的属性。对于那些没有。 (注意:请记住,python词典不支持重复键,这就是为什么我建议在下面存储作为键列表索引,否则你将不得不找到一种方法使密钥不同)

例如,列表如下:

l = [item1,item2,None,item4]

你可以创建一个字典:

d = {item1:"thing1", item2:"thing2", None:"No_attr", item3:"thing3"}

因此,每当您需要进行检查时,您不必检查两个条件,但您只能检查值,例如:

if d.values()[your_index]=="thing":

此方法的唯一缺点是标准的python词典本质上无序,这使得通过索引访问字典值有时会有点危险 - 你必须小心不要改变字典的形式排列。

现在,如果您想确保索引保持稳定,那么您必须以某种方式存储它,例如选择字典的索引,因为您已经存储了项目的属性 - ,这是您必须决定的,并且在很大程度上取决于项目的体系结构。

  

使用列表:

在使用list的方式时,我认为没有办法避免你的if语句 - 实际上也不错。也许使用and运算符,因为在另一个答案中已经提到过,但我认为这无论如何都没有任何区别。

,如果您想使用第一种方法: if ins_list[ind].some_attribute == "thing":

您可以尝试使用和例外捕获器:

try:
    if ins_list[ind].some_attribute == "thing":
        #do something
except:  
    #an error occured
    pass

答案 1 :(得分:0)

使用布尔运算符and

if ins_list[ind] and ins_list[ind].some_attribute == "thing":
    # Code

答案 2 :(得分:0)

正如编码人员提议的那样,您可以从列表中删除None,或者使用词典,以避免必须为每个索引创建条目。

我想提出另一种方法:你可以创建一个虚拟类并用它替换None。这样,如果设置属性,则不会出现错误:

class dummy:
    def __nonzero__(self):
        return False
    def __setattr__(self, k, v):
        return


mydummy = dummy()
mylist = [ins_1, ins_2, mydummy, ins_3, mydummy]

设置属性

时,不会将任何内容存储到虚拟实例中

修改

如果无法选择原始列表的内容,则此类可以提供帮助:

class PickyList(list):
    def __init__(self, iterable, dummyval):
        self.dummy = dummyval
        return super(PickyList, self).__init__(iterable)
    def __getitem__(self, k):
        v = super(PickyList, self).__getitem__(k)
        return (self.dummy if v is None else v)



mylist = PickyList(ins_list, mydummy)

答案 3 :(得分:0)

在这种情况下,我会使用try-except语句,因为EAFP (更容易要求原谅而不是权限)。它不会缩短你的代码,但在检查有效属性时,它是一种更加Pythonic的代码编码方式。这样你就不会打破DRY (不要自己重拍)

try:
    if ins_list[ind].some_attribute == "thing":
        # do_something()
except AttributeError:
    # do_something_else()