引用Python 从新手到专家
的例子:
def info(object, spacing=10, collapse=1): """Print methods and doc strings. Takes module, class, list, dictionary, or string.""" methodList = [method for method in dir(object) if callable(getattr(object, method))]
'getattr(对象,方法,默认返回值) 是返回函数引用 ,相当于函数指针'
processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)'这是一个函数引用,可以理解为函数指针'
print "\n".join(["%s %s" % '''字符串格式化''' (method.ljust(spacing), processFunc(str(getattr(object, method).__doc__))) for method in methodList]) if __name__ == "__main__": print info.__doc__
看到这段代码最让我困惑的地方就是:
methodList = [method for method in dir(object) if callable(getattr(object, method))]对于什么别的陌生的函数,直接help() 或者百度都能找到答案,但就这句话,让我怎么没明白什么意思,后来请教别人,别人就
给我推荐了一本书《python核心编程》 结果在一个鸟不拉屎的地方找到了,关于列表解析
4.5. 过滤列表
如你所知,Python 具有通过列表解析 (第 3.6 节 “映射 list”) 将列表映射到其它列表的强大能力。这种能力同过滤机制结合使用,使列表中的有些元素被映射的同时跳过另外一些元素。
过滤列表语法:
[mapping-expression for element in source-list if filter-expression]
这是你所知所爱的列表解析的扩展。前三部分都是相同的;最后一部分,以 if 开头的是过滤器表达式。过滤器表达式可以是返回值为真或者假的任何表达式 (在 Python 中是几乎任何东西)。任何经过滤器表达式演算值为真的元素都可以包含在映射中。其它的元素都将忽略,它们不会进入映射表达式,更不会包含在输出列表中。
例 4.14. 列表过滤介绍
>>> li = ["a", "mpilgrim", "foo", "b", "c", "b", "d", "d"] >>> [elem for elem in li if len(elem) > 1]['mpilgrim', 'foo'] >>> [elem for elem in li if elem != "b"]
['a', 'mpilgrim', 'foo', 'c', 'd', 'd'] >>> [elem for elem in li if li.count(elem) == 1]
['a', 'mpilgrim', 'foo', 'c']
回到 apihelper.py 中的这一行:
methodList = [method for method in dir(object) if callable(getattr(object, method))]
这行看上去挺复杂――确实也很复杂――但是基本结构都还是一样的。整个过滤表达式返回一个列表,并赋值给 methodList 变量。表达式的前半部分是列表映射部分。映射表达式是一个和遍历元素相同的表达式,因此它返回每个元素的值。dir(object) 返回 object 对象的属性和方法列表――你正在映射的列表。所以唯一新出现的部分就是在 if 后面的过滤表达式。
过滤表达式看上去很恐怖,其实不是。你已经知道了 callable、getattr 和 in。正如你在前面的部分中看到的,如果 object 是一个模块,并且 method 是上述模块中某个函数的名称,那么表达式 getattr(object, method) 将返回一个函数对象。
所以这个表达式接收一个名为 object 的对象,然后得到它的属性、方法、函数和其他成员的名称列表,接着过滤掉我们不关心的成员。执行过滤行为是通过对每个属性/方法/函数的名称调用getattr 函数取得实际成员的引用,然后检查这些成员对象是否是可调用的,当然这些可调用的成员对象可能是方法或者函数,同时也可能是内置的 (比如列表的 pop 方法) 或者用户自定义的 (比如 odbchelper 模块的 buildConnectionString 函数)。这里你不用关心其它的属性,如内置在每一个模块中的 __name__ 属性。
def info(object, spacing=10, collapse=1):![]()
![]()
"""Print methods and doc strings. Takes module, class, list, dictionary, or string.""" methodList = [method for method in dir(object) if callable(getattr(object, method))] processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s) print "\n".join(["%s %s" % (method.ljust(spacing), processFunc(str(getattr(object, method).__doc__))) for method in methodList]) if __name__ == "__main__":
![]()
print info.__doc__