4.8. 全部放在一起
最后一行代码是唯一还没有解释过的,它完成全部的工作。但是现在工作已经简单了,因为所需要的每件事都已经按照需求建立好了。所有的多米诺骨牌已经就位,到了将它们推倒的时候了。
下面是 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
遍历列表。
例 4.22. 动态得到 doc string
>>> 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.
[1] | 在 info 函数中,object 是要得到帮助的对象,作为一个参数传入。 |
[2] | 在你遍历 methodList 时,method 是当前方法的名称。 |
[3] | 通过 getattr 函数,你可以得到 object 模块中 method 函数的引用。 |
[4] | 现在,很容易就可以打印出方法的 doc string 。 |
接下来令人困惑的是 doc string
周围 str
的使用。你可能记得,str
是一个内置函数,它可以强制将数据转化为字符串。但是一个 doc string
应该总是一个字符串,为什么还要费事地使用 str
函数呢?答案就是:不是每个函数都有 doc string
,如果没有,这个 __doc__
属性为 None
。
例 4.23. 为什么对一个 doc string
使用 str
?
>>> >>> def foo(): print 2
>>> >>> foo()
2
>>> >>> foo.__doc__
>>> foo.__doc__ == None
True
>>> str(foo.__doc__)
'None'
[1] | 你可以很容易的定义一个没有 doc string 的函数,这种情况下它的 __doc__ 属性为 None 。令人迷惑的是,如果你直接演算 __doc__ 属性的值,Python IDE 什么都不会打印。这是有意义的 (前提是你考虑了这个结果的来由),但是却没有什么用。 |
[2] | 你可以直接通过 __doc__ 属性和 None 的比较验证 __doc__ 属性的值。 |
[3] | str 函数可以接收值为 null 的参数,然后返回它的字符串表示,'None' 。 |
注意
在 SQL 中,你必须使用IS NULL
代替= NULL
进行 null 值比较。在 Python,你可以使用== None
或者is None
进行比较,但是is None
更快。
现在你确保有了一个字符串,可以把这个字符串传给 processFunc
,这个函数已经定义是一个既可以压缩空白也可以不压缩空白的函数。现在你看出来为什么使用 str
将 None
转化为一个字符串很重要了。processFunc
假设接收到一个字符串参数然后调用 split
方法,如果你传入 None
,将导致程序崩溃,因为 None
没有 split
方法。
再往回走一步,你再一次使用了字符串格式化来连接 processFunc
的返回值 和 method
的 ljust
方法的返回值。ljust
是一个你之前没有见过的新字符串方法。
例 4.24. ljust
方法介绍
>>> s = 'buildConnectionString'
>>> s.ljust(30)
'buildConnectionString '
>>> s.ljust(20)
'buildConnectionString'
[1] | ljust 用空格填充字符串以符合指定的长度。info 函数使用它生成了两列输出并将所有在第二列的 doc string 纵向对齐。 |
[2] | 如果指定的长度小于字符串的长度,ljust 将简单地返回未变化的字符串。它决不会截断字符串。 |
几乎已经完成了。有了 ljust
方法填充过的方法名称和来自调用 processFunc
方法得到的 doc string
(可能压缩过),你就可以将两者连接起来并得到单个字符串。因为对 methodList
进行了映射,最终你将获得一个字符串列表。利用 "\n"
的 join
函数,将这个列表连接为单个字符串,列表中每个元素独占一行,接着打印出结果。
例 4.25. 打印列表
>>> li = ['a', 'b', 'c']
>>> print "\n".join(li)
a
b
c
[1] | 在你处理列表时,这确实是一个有用的调试技巧。在 Python 中,你会十分频繁地操作列表。 |
上述就是最后一个令人困惑的地方了。但是现在你应该已经理解这段代码了。
print "\n".join(["%s %s" %
(method.ljust(spacing),
processFunc(str(getattr(object, method).__doc__)))
for method in methodList])