首页 > 深入Python > 自省的威力 > 过滤列表 | << >> |
diveintopython.org |
|
Python for experienced programmers |
你已经知道了,Python拥有强大的映射列表到其它列表的能力。它可以同一种过滤机制合并,即列表中的某此元素被映射,而其它的被完全忽略。
[mapping-expression for element in source-list if filter-expression]
前三分之二的表达式应该看上去熟悉了,因为它与列表映射有着相同的结构。最后一部分,以 if 开始的,就是过滤表达式。一个过滤表达式可以是任意地计算真假值的表达式(这在Python中可能是几乎任何东西)。任何对于过滤表达式计算出真值的元素将包括在映射中。其它所有元素被忽略掉,所以它们不会进入映射表达式,并且也不被包括在输出列表中。
>>> 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']
typeList = (BuiltinFunctionType, BuiltinMethodType, FunctionType, MethodType, ClassType) methodList = [method for method in dir(object) if type(getattr(object, method)) in typeList]
这个看上去挺复杂的,它的确复杂,但是基本结构是一样的。整个过滤表达式返回一个列表,列表赋给 methodList 变量。表达式的前半部分是列表映射部分。映射表达式是一个相同的表达式,它返回每个元素的值。dir(object) 返回一个对象的属性和方法的列表,那就是你正在映射的列表。所以唯一新的部分就是在 if 后面的过滤表达式。
过滤表达式看上去很恐怖,但其实不是。你已经知道了type,getattr,和in了。正如你在前面部分中看到的,如果 object 是一个模块,并且 method 是在那个模块中函数的名字,表达式 getattr(object, method) 返回一个函数对象。
所以这个表达式接收一个名为 object 的对象,得到它的属性,方法,和一些其它东西的名字列表,然后过滤那个列表来除掉所有我们不关心的东西。我们执行过滤是通过得到每个属性/方法/函数的名字,然后通过 getattr 函数得到指向实际东西的引用。然后我们用 type 函数来检查对象的类型,接着查看是否那个类型是我们所关心的东西之一。特别地,我们关心方法和函数,内置的(如一个列表的 pop 方法)和用户自定义的(如 odbchelper 模块中的 buildConnectionString 函数)。我们不关心其它的属性,如内置在每一个模块中的 __name__ 属性。
你可能已经注意到过滤表达式也包括了类型为 ClassType 的对象。现在不要对此担心,当我们进行到第三章中的面向对象概念时,我们将讨论Python的类(译注:原文为“Don't worry about this for now; we'll discuss Python classes ad nauseum when we get into object-oriented concepts in chapter 3.”,不知道 ad nauseum 是什么意思。)。
进一步阅读 |
|
« 使用 getattr 得到对象各种引用 | and-or 技巧 » |