先来看一段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))] 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]) 我们来调用此函数 >>> from apihelper import info >>> li = [] >>> info(li) append L.append(object) -- append object to end count L.count(value) -> integer -- return number of occurrences of value extend L.extend(list) -- extend list by appending list elements index L.index(value) -> integer -- return index of first occurrence of value insert L.insert(index, object) -- insert object before index pop L.pop([index]) -> item -- remove and return item at index (default last) remove L.remove(value) -- remove first occurrence of value reverse L.reverse() -- reverse *IN PLACE* sort L.sort([cmpfunc]) -- sort *IN PLACE*; if given, cmpfunc(x, y) -> -1, 0, 1 此函数可以接受任何含有函数或者方法的对象 (比如模块,含有函数,又比如list,含有方法) 作为参数,并打印出对象的所有函数和它们的 doc string 下面我们来解释一下该函数 def info(object, spacing=10, collapse=1): 还记得函数中的默认参数和关键参数吗 Python中函数的参数可以看成是一个字典,所以不需要按顺序给形参赋值,可以按任何顺序,只要key对了就可以。 methodList = [method for method in dir(object) if callable(getattr(object, method))] 要理解这一行代码,首先需要想起映射list 而这里将映射list跟过滤机制结合 语法如下: [mapping-expression for element in source-list if filter-expression] 以 if 开头的是过滤器表达式 然后需要知道几个内置函数 (Python 内置函数都归组到了 __builtin__ (前后分别是双下划线) 这个特殊的模块中。你可以认为 Python 在启动时自动执行了 from __builtin__ import *,此语句将所有的 “内置” 函数导入该命名空间,所以在这个命名空间中可以直接使用这些内置函数。) 首先dir()函数 dir 函数返回任意对象的属性和方法列表,包括模块对象、函数对象、字符串对象、列表对象、字典对象 …… 相当多的东西。 >>> li = [] >>> dir(li) ['append', 'count', 'extend', 'index', 'insert','pop', 'remove', 'reverse', 'sort'] >>> d = {} >>> dir(d) ['clear', 'copy', 'get', 'has_key', 'items', 'keys', 'setdefault', 'update', 'values'] >>> import odbchelper >>> dir(odbchelper) ['__builtins__', '__doc__', '__file__', '__name__', 'buildConnectionString'] getattr()函数 首先我们要知道函数也是一个对象,所以也有引用指向一个函数对象,而getattr()函数就是获取指向对象(包括函数)的引用,如以下两种方法是等价的: 1. >>> li=[] >>> li.append('1') >>> li ['1'] 2. >>> li=[] >>> getattr(li,'append')('1') getattr(li,'append')获取了li的append函数对象的引用,所以就可以使用该函数了 >>> li ['1'] getattr 常见的使用模式是作为一个分发者, 例如statsout 模块定义了三个函数:output_html、output_xml 和 output_text。然后主程序定义了唯一的输出函数,如下: import statsout def output(data, format="text"): output_function = getattr(statsout, "output_%s" % format) return output_function(data) output 函数接收一个必备参数 data,和一个可选参数 format。如果没有指定 format 参数,其缺省值是 text 并完成普通文本输出函数的调用。 getattr 能够使用可选的第三个参数,一个缺省返回值: import statsout def output(data, format="text"): output_function = getattr(statsout, "output_%s" % format, statsout.output_text) return output_function(data) 这个函数调用一定可以工作,因为你在调用 getattr 时添加了第三个参数。第三个参数是一个缺省返回值,如果第二个参数指定的属性或者方法没能找到,则将返回这个缺省返回值 callable() 函数 它接收任何对象作为参数,如果参数对象是可调用的,返回 True;否则返回 False。可调用对象包括函数、类方法,甚至类自身。 processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s) 要理解这句代码,需要了解Python里的and or 及 lambda函数 在Python 中,and 和 or 执行布尔逻辑演算。但是它们并不返回布尔值,而是返回它们实际进行比较的值之一。 首先必须要知道的是Python中0、''、[]、()、{}、None 在布尔环境中为假;其它任何东西都为真。 先看 and 如果and的值都为真 就返回最后一个真值 如果有一个值为假 就返回第一个假值 再看or 如果or的值都为假 就返回最后一个假值 如果有一个值为真 就返回第一个真值 >>> a = "first" >>> b = "second" >>> 1 and a or b 'first' >>> 0 and a or b 'second' 这个语法看起来类似于 C 语言中的 bool ? a : b 表达式,但如果a为假值,得到的结果就不是你想要的了,可以这样: >>> a = "" >>> b = "second" >>> (1 and [a] or [b])[0] '' 由于 [a] 是一个非空列表,所以它决不会为假。即使 a 是 0 或者 '' 或者其它假值,列表 [a] 也为真,因为它有一个元素。 lambda函数 Python 支持一种有趣的语法,它允许你快速定义单行的最小函数。这些叫做 lambda 的函数,是从 Lisp 借用来的,可以用在任何需要函数的地方。 >>> def f(x): ... return x*2 ... >>> f(3) 6 >>> g = lambda x: x*2 >>> g(3) 6 >>> (lambda x: x*2)(3) 6 lambda 函数,完成同上面普通函数相同的事情,lambda 函数没有函数名称,但是可以将它赋值给一个变量进行调用,甚至不需要将它赋值给一个变量。 注意这句代码还加了and-or 而lambda 函数在布尔环境中总是为真 所以collapse为真时取第一lambda函数 collapse为假时取第二个lambda函数 split()不带参数时,按空白进行分割 >>> s = "this is\na\ttest" >>> print s this is a test >>> print s.split() ['this', 'is', 'a', 'test'] 最后一句
print "\n".join(["%s %s" %
(method.ljust(spacing),
processFunc(str(getattr(object, method).__doc__)))
for method in methodList])
首先该语句用到了映射list,然后有两个函数 str()将数据强制转换为字符串。每种数据类型都可以强制转换为字符串。
ljust()函数
>>> s = 'buildConnectionString' >>> s.ljust(30) 'buildConnectionString ' >>> s.ljust(20) 'buildConnectionString' ljust 用空格填充字符串以符合指定的长度。如果指定的长度小于字符串的长度,ljust 将简单地返回未变化的字符串。它决不会截断字符串。 |
|