在Python中遍历对象

3
如何避免无限制地重复自己而编写这段代码呢?
fields = row.split('__')

if len(fields) == 1:
    foo = getattr(bundle.obj, fields[0])
elif len(fields) == 2:
    foo = getattr(getattr(bundle.obj, fields[0]), fields[1])
elif len(fields) == 3:
    foo = getattr(getattr(getattr(bundle.obj,
                            fields[0]), fields[1]), fields[2])
# etc ..
1个回答

10

使用reduce()函数:

foo = reduce(getattr, fields, bundle.obj)

或者使用一个简单的循环:

foo = bundle.obj
for field in fields:
    foo = getattr(foo, field)

我感觉每天都会学到另一个非常有用的内置函数。Guido真是一个聪明而仁慈的独裁者 :) - Jason Sperske
@JasonSperske:实际上,Guido不记得是谁在早期说服他添加reduce的,但自那以后他一直想摆脱它。许多其他核心开发人员也同意他的看法。他们非常讨厌它,在3.0转换中,他们勉强同意将其移动到functools,并停止谈论它,而不是完全删除它。(就我个人而言,我认为有些情况下reduce可以使事情更易读——虽然很少,但这绝对是其中之一。) - abarnert
@abarnert:毫无疑问,那是那些讨厌的Lisp人之一。 :D (我会说“我们之一”,但我从来没有写过太多的Lisp,即使当我和AI研究生们一起闲逛时....)map也有很多抱怨吧? - torek
@JasonSperske:我认为这很大程度上取决于个人口味和历史知识。mapreduce都来自于各种函数式语言,Python的许多部分也是从其他语言中借鉴(我是说抄袭)而来的。将思想与可行的语法等正确地融合在一起,这就需要“口味”的参与了。Python有这种能力,但Perl就不太行。:D - torek
@torek: 少得多了。Guido最初建议在添加理解式时摆脱mapfilter,但由于各种人开始使用mapreduce进行对比(例如“并非所有函数工具都像reduce一样无用-看看map,每个人都喜欢内置的”),他已经转变了想法。 - abarnert
此外,他们并不完全错误:mapfilter从conses到数组和迭代器的转换比fold/reduce更好。 (Haskell只通过为您提供实际上是O(1)的方法来切片无限惰性列表,使fold与之配合使用。) - abarnert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接