导航:起始页 > Dive Into Python > 自省的威力 > 全部放在一起 | << >> | ||||
深入 Python :Dive Into Python 中文版Python 从新手到专家 [Dip_5.4b_CPyUG_Release] |
最后一行代码是唯一还没有解释过的,它完成全部的工作。但是现在工作已经简单了,因为所需要的每件事都已经按照需求建立好了。所有的多米诺骨牌已经就位,到了将它们推倒的时候了。
下面是 apihelper.py 的关键
print "\n".join(["%s %s" % (method.ljust(spacing), processFunc(str(getattr(object, method).__doc__))) for method in methodList])
注意这是一条命令,被分隔成了多行,但是并没有使用续行符 (\)。还记得我说过一些表达式可以分割成多行而不需要使用反斜线吗?列表解析就是这些表达式之一,因为整个表达式包括在方括号里。
现在,让我们从后向前分析。
for method in methodList
告诉我们这是一个列表解析。如你所知 methodList 是 object 中所有你关心的方法的一个列表。所以你正在使用 method 遍历列表。
>>> import odbchelper >>> object = odbchelper >>> method = 'buildConnectionString' >>> getattr(object, method) <function buildConnectionString at 010D6D74> >>> print getattr(object, method).__doc__ Build a connection string from a dictionary of parameters. Returns string.
在 info 函数中,object 是要得到帮助的对象,作为一个参数传入。 | |
在你遍历 methodList 时,method 是当前方法的名称。 | |
通过 getattr 函数,你可以得到 object 模块中 method 函数的引用。 | |
现在,很容易就可以打印出方法的 doc string 。 |
接下来令人困惑的是 doc string 周围 str 的使用。你可能记得,str 是一个内置函数,它可以强制将数据转化为字符串。但是一个 doc string 应该总是一个字符串,为什么还要费事地使用 str 函数呢?答案就是:不是每个函数都有 doc string ,如果没有,这个 __doc__ 属性为 None。
>>> >>> def foo(): print 2 >>> >>> foo() 2 >>> >>> foo.__doc__ >>> foo.__doc__ == None True >>> str(foo.__doc__) 'None'
在 SQL 中,你必须使用 IS NULL 代替 = NULL 进行 null 值比较。在 Python,你可以使用 == None 或者 is None 进行比较,但是 is None 更快。 |
现在你确保有了一个字符串,可以把这个字符串传给 processFunc,这个函数已经定义是一个既可以压缩空白也可以不压缩空白的函数。现在你看出来为什么使用 str 将 None 转化为一个字符串很重要了。processFunc 假设接收到一个字符串参数然后调用 split 方法,如果你传入 None ,将导致程序崩溃,因为 None 没有 split 方法。
再往回走一步,你再一次使用了字符串格式化来连接 processFunc 的返回值 和 method 的 ljust 方法的返回值。ljust 是一个你之前没有见过的新字符串方法。
>>> s = 'buildConnectionString' >>> s.ljust(30) 'buildConnectionString ' >>> s.ljust(20) 'buildConnectionString'
几乎已经完成了。有了 ljust 方法填充过的方法名称和来自调用 processFunc 方法得到的 doc string (可能压缩过),你就可以将两者连接起来并得到单个字符串。因为对 methodList 进行了映射,最终你将获得一个字符串列表。利用 "\n" 的 join 函数,将这个列表连接为单个字符串,列表中每个元素独占一行,接着打印出结果。
上述就是最后一个令人困惑的地方了。但是现在你应该已经理解这段代码了。
print "\n".join(["%s %s" % (method.ljust(spacing), processFunc(str(getattr(object, method).__doc__))) for method in methodList])
<< 使用 lambda 函数 |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
小结 >> |