验证嵌套类中的属性

时间:2016-03-28 09:40:13

标签: python

class first:
    class second:
        class third:
            class forth:
                val = "test"

我想安全地检索变量'val',如果'val'不存在,我想返回False(而不是显示错误)

我知道我可以使用这样的逻辑运算符:

打印first.second和first.second.third和first.second.third.forth和first.second.third.forth.val或False

或将其置于'try ... except'块中,如下所示:

try :
    print first.second.third.forth.val
except AttributeError:
    pass

但上面的两个例子都太长了,特别是当它们的嵌套类太多时

我的问题是,还有其他更简单的方法吗?我希望有类似的东西? C#中的运算符或至少可以安全评估它且易于阅读的函数。

我的问题类似于这个问题:How to know if an object has an attribute in Python

但区别在于我的是嵌套类,如果我使用hasattr()或getattr(),当一个类缺少这样的时候我仍会有错误:

>>> class first:
...         class second:
...             class third:
...                 class forth:
...                     val = "test"
... 
>>> hasattr(first.second.third.forth.fifth,'val')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: class forth has no attribute 'fifth'

但它确实让我有了创建这样一个函数的想法:

>>> def eval(cls, args, default=False):
...     for arg in args.split('.') :
...         if not hasattr(cls,arg) : return default
...         cls = getattr(cls,arg)
...     return cls
... 
>>> eval(first,'second.third.forth.val','Default Value')
'test'
>>> eval(first,'second.third.forth.fifth','Default Value')
'Default Value'

3 个答案:

答案 0 :(得分:1)

这可能是个人品味的问题,但Python中有"better ask forgiveness than permission" school of thought,您的try/except适合那里。 (我会那样做,FWIW。)

关于多重嵌套导致的长表达式:

  1. 考虑一下在任何情况下你是否真的需要这么多的嵌套。
  2. 如果您确实需要这么多嵌套,但访问表达式太长,您可以将其分解:

    try :
        second = first.second
        third = second.third
        forth = third.forth
        print forth.val
    except AttributeError:
        pass
    

答案 1 :(得分:0)

我回答了我自己的问题,以便将其标记为已解决。

我目前正在使用此方法,如果您有更好的解决方案,请告诉我。

>>> def eval(cls, args, default=False):
...     for arg in args.split('.') :
...         if not hasattr(cls,arg) : return default
...         cls = getattr(cls,arg)
...     return cls
... 
>>> eval(first,'second.third.forth.val','Default Value')
'test'
>>> eval(first,'second.third.forth.fifth','Default Value')
'Default Value'

答案 2 :(得分:-1)

string value = first.second.third.forth.val; bool isValue = string.NullOrEmpty(value)? false:value;