💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# 4.8. 全部放在一起 最后一行代码是唯一还没有解释过的,它完成全部的工作。但是现在工作已经简单了,因为所需要的每件事都已经按照需求建立好了。所有的多米诺骨牌已经就位,到了将它们推倒的时候了。 下面是 `apihelper.py` 的关键 ``` print "\n".join(["%s %s" % (method.ljust(spacing), processFunc(str(getattr(object, method).__doc__))) for method in methodList]) ``` 注意这是一条命令,被分隔成了多行,但是并没有使用续行符 (`\`)。还记得我说过[一些表达式可以分割成多行](../native_data_types/declaring_variables.html#tip.implicitmultiline)而不需要使用反斜线吗?列表解析就是这些表达式之一,因为整个表达式包括在方括号里。 现在,让我们从后向前分析。 ``` for method in methodList ``` 告诉我们这是一个[列表解析](../native_data_types/mapping_lists.html "3.6. 映射 list")。如你所知 `methodList` 是 `object` 中[所有你关心的方法](filtering_lists.html#apihelper.filter.care)的一个列表。所以你正在使用 `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`](getattr.html "4.4. 通过 getattr 获取对象引用") 函数,你可以得到 _`object`_ 模块中 _`method`_ 函数的引用。 | | \[4\] | 现在,很容易就可以打印出方法的 `doc string` 。 | 接下来令人困惑的是 `doc string` 周围 `str` 的使用。你可能记得,`str` 是一个内置函数,它可以[强制将数据转化为字符串](built_in_functions.html "4.3. 使用 type、str、dir 和其它内置函数")。但是一个 `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`,这个函数[已经定义](lambda_functions.html "4.7. 使用 lambda 函数")是一个既可以压缩空白也可以不压缩空白的函数。现在你看出来为什么使用 `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]) ```