Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
获取getattr()的简明方法,如果在Python中没有,请使用它_Python - Fatal编程技术网

获取getattr()的简明方法,如果在Python中没有,请使用它

获取getattr()的简明方法,如果在Python中没有,请使用它,python,Python,我发现自己经常做以下事情: attr = getattr(obj, 'attr', None) if attr is not None: attr() # Do something, either attr(), or func(attr), or whatever else: # Do something else 有没有一种更像蟒蛇的写作方式?这样更好吗?(国际海事组织,至少在性能方面没有) 还有一个很好的成语: if hasattr(obj, 'attr'):

我发现自己经常做以下事情:

attr = getattr(obj, 'attr', None)
if attr is not None:
    attr()
    # Do something, either attr(), or func(attr), or whatever
else:
    # Do something else

有没有一种更像蟒蛇的写作方式?这样更好吗?(国际海事组织,至少在性能方面没有)


还有一个很好的成语:

if hasattr(obj, 'attr'):
    ...something...
else:
    ...something else...

从你发布的两个选项中,我更喜欢第一个。访问成员时抛出异常的概念似乎与异常的用途不同。

使用try/except通常被认为更像python。如果obj确实具有该属性,那么它也会更有效,因为它消除了测试-尝试块,并且在没有引发异常的情况下没有开销。另一方面,如果obj没有该属性,则效率较低,因为它将有抛出和捕获异常的开销。

在编写代码时,try/
exception替代方法可能会意外地导致由调用的任何
attr()
中的问题导致的
AttributeError
,被抓住。如果要使用
进行编码,请尝试使用
/
进行编码,但
除外,这是合理的,如果属性很少丢失,则性能相当好,请使用:

try:
  attr = obj.attr
except AttributeError:
  dosome(thingelse)
else:
  attr()

这不会导致上述“意外捕捉”。至于哪种方法更可取,我通常使用异常捕获方法——“EAFP”,“请求原谅比允许更容易”(这句格言经常被认为是COBOL和CODASYL背后的驱动力——格雷斯·霍珀上将的座右铭),它肯定适用于Python;-)

啊,这取决于确切的代码。您的两个工具:

  • 当且仅当obj.attr存在时,hasattr(obj,'attr')返回True
  • getattr(obj,'attr',other_值)返回obj.attr(如果存在),否则返回other_值
  • 尝试a=obj.attr/except failure()/else在性能超过可读性时执行(a)
以下是最常见的情况:

 the_name = getattr(user, 'name', '<Unknown User>')
 user.name = getattr(user, 'name', '<Unknown User>')
 if not hasattr(name, 'user'):
    try_asking_again()
 name = user.name if hasattr(user, 'name') else do_expensive_name_lookup(user)
其中有以下输出:

hasattr(a) is True
a is A
hasattr(b) is True
b is B
No C
and c is also Not Assigned
Traceback (most recent call last):
  File "attr_snippet.py", line 23, in <module>
    print "c throws an Attribute exception " + item.c
  File "attr_snippet.py", line 9, in __getattr__
    raise AttributeError("Thing instance has no attribute '" + attr + "'")
AttributeError: Thing instance has no attribute 'c'
hasattr(a)为真
a是a
hasattr(b)是真的
b是b
没有C
c也没有赋值
回溯(最近一次呼叫最后一次):
文件“attr_snippet.py”,第23行,在
打印“c抛出属性异常”+item.c
文件“attr\u snippet.py”,第9行,在\uu getattr中__
raise AttributeError(“对象实例没有属性'+attr+''))
AttributeError:对象实例没有属性“c”

既然您正在调用
attr
,您可以执行以下操作:

def default_action():
    # do something else

action = getattr(obj, 'attr', default_action)

action()

与Joe的答案相似,但较短:

getattr(obj, 'attr', lambda: None)()

“至少没有表现,国际海事组织”。你应该测量一下。你会发现Python异常非常快。如果它实际上是一个瓶颈(可能不是),那么性能也取决于常见的情况——属性通常存在还是不存在?可能是pythonic,但它很丑陋,我相信异常并不是为了这种目的。在python中,您甚至可以捕捉到
缩进错误
,这是否也是pythonic,用于包围某些您不确定缩进是否正确的代码?为什么不是?假设您正在导入一个插件模块,但该模块无法导入。抛出的异常说明了原因。如果您有动机这样做,您可以捕获错误并准确地告诉用户如何修复它(“清除文件Y第X行的缩进问题”)。我很欣赏这种灵活性。我要求您“围绕一些没有用try块正确缩进的代码”。。。。您必须更加间接,因为解析器将在
try:
结构完成之前发现问题。这实际上是一个真实的示例。我在一个项目中测试一些代码,不知道为什么它会失败,也不知道为什么我的调试语句没有打印出来。结果是有人尝试了:。。。除了异常:
在某个地方,当我更正它以只捕获特定的异常时,结果发现有一个
缩进错误
:-)。很有趣,但很可怕。我从来没有想过这一点,但对于我的一些用例来说,这确实是完美的-1因为AttributeError是“访问成员时”使用的一个非常明显的例外。这是一个悬而未决的问题。我不认为在这种情况下使用
AttributeError
是一种很好的做法,你确实这么认为。这是否意味着你是对的而我不是?我认为索伊斯,这不管用。在大多数情况下,我仍然会使用try/except方法,因为它更容易向其他人阅读。
def default_action():
    # do something else

action = getattr(obj, 'attr', default_action)

action()
getattr(obj, 'attr', lambda: None)()