Dive into Python Chapter4

Chapter 4. 自省

apihelper.py

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]))

if __name__ == '__main__':
  print(info._doc__)

用法示例

>>> 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

缺省地,程序输出进行了格式化处理,以使其易于阅读。多行 doc string 被合
并到单行中,要改变这个选项需要指定 collapse 参数的值为 0。如果函数名称
长于 10 个字符,你可以将 spacing 参数的值指定为更大的值以使输出更容易阅
读。

apihelper的高级用法

>>> import odbchelper
>>> info(odbchelper)
buildConnectionString Build a connection string from a dictionary Returns string.
>>> info(odbchelper, 30)
buildConnectionString Build a connection string from a dictionary Returns string.
>>> info(odbchelper, 30, 0)
buildConnectionString Build a connection string from a dictionary

Returns string.

可选参数

def info(object, spacing=10, collapse=1):

spacing 和 collapse 是可选参数,因为它们已经定义了缺省值。object 是必备参数,因为它没有指定缺省值。

命名参数

在 Python 中,参数可以通过名称以任意顺序指定。

info(odbchelper)
info(odbchelper, 12)
info(odbchelper, collapse=0)
info(spacing=15, object=odbchelper)

使用内置函数 type, str, dir

  1. type函数
>>> type(1) (1)

>>> li = []
>>> type(li) (2)

>>> import odbchelper
>>> type(odbchelper) (3)

>>> import types (4)
>>> type(odbchelper) == types.ModuleType
True
  • 整型、字符串、列表、字典、元组、函数、类、模块,甚至类
    型对象都可以作为参数被 type 函数接受
  • 可以使用 types 模块中的常量来进行对象类型的比较
  • str函数
    str 将数据强制转换为字符串。每种数据类型都可以强制转换为字符串
>>> str(1) (1)
'1'
>>> horsemen = ['war', 'pestilence', 'famine']
>>> horsemen
['war', 'pestilence', 'famine']
>>> horsemen.append('Powerbuilder')
>>> str(horsemen) (2)
"['war', 'pestilence', 'famine', 'Powerbuilder']"
>>> str(odbchelper) (3)
""
>>> str(None) (4)
'None'
  • dir函数
    dir 函数返回任意对象的属性和方法列表,包括模块对象、函数对象、字符串对象、列表对象、字典对象 ……
>>> li = []
>>> dir(li) (1)
['append', 'count', 'extend', 'index', 'insert',
'pop', 'remove', 'reverse', 'sort']
>>> d = {}
>>> dir(d) (2)
['clear', 'copy', 'get', 'has_key', 'items', 'keys', 'setdefault', 'update', 'values']
>>> import odbchelper
>>> dir(odbchelper) (3)
['__builtins__', '__doc__', '__file__', '__name__', 'buildConnectionString']
  • callable函数
    它接收任何对象作为参数,如果参数对象是可调用的,返回 True;否则返回 False。可调用对象包括函数、类方法,甚至类自身。
>>> import string
>>> string.punctuation (1)
'!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
>>> string.join (2)

>>> callable(string.punctuation) (3)
False
>>> callable(string.join) (4)
True

通过getattr获取对象引用

使用 getattr 函数,可以得到一个直到运行时才知道名称的函数的引用。

>>> li = ["Larry", "Curly"]
>>> li.pop (1)

>>> getattr(li, "pop") (2)

>>> getattr(li, "append")("Moe") (3)
>>> li
["Larry", "Curly", "Moe"]
>>> getattr({}, "clear") (4)

用于模块的getattr

>>> import odbchelper
>>> odbchelper.buildConnectionString (1)

>>> getattr(odbchelper, "buildConnectionString") (2)

>>> object = odbchelper
>>> method = "buildConnectionString"
>>> getattr(object, method) (3)

>>> type(getattr(object, method)) (4)

>>> import types
>>> type(getattr(object, method)) == types.FunctionType
True
>>> callable(getattr(object, method)) (5)
True

使用getattr创建分发者

import statsout
def output(data, format="text"):
  output_function = getattr(statsout, "output_%s" % format)
  return output_function(data)

如果用户传入一个格式参数,但是在 statsout 中没有定义相应的格式输出函数,会发生什么呢?还好,getattr 会返回 None,它会取代一个有效函数并被赋值给 output_function,然后下一行调用函数的语句将会失败并抛出一个异常。这种方式不好。值得庆幸的是,getattr 能够使用可选的第三个参数,一个缺省返回值。

getattr缺省值

import statsout
def output(data, format="text"):
  output_function = getattr(statsout, "output_%s" % format, statsout.output_text)
  return output_function(data)

这个函数调用一定可以工作,因为你在调用 getattr 时添加了第三个参数。第三个参数是一个缺省返回值,如果第二个参数指定的属性或者方法没能找到,则将返回这个缺省返回值。

过滤列表

语法
[mapping-expression for element in source-list if filter-expression]

>>> li = ["a", "mpilgrim", "foo", "b", "c", "b", "d", "d"]
>>> [elem for elem in li if len(elem) > 1] (1)
['mpilgrim', 'foo']
>>> [elem for elem in li if elem != "b"] (2)
['a', 'mpilgrim', 'foo', 'c', 'd', 'd']
>>> [elem for elem in li if li.count(elem) == 1] (3)
['a', 'mpilgrim', 'foo', 'c']

回到apihelper.py中的这一行:

methodList = [method for method in dir(object) if callable(getattr(object, method))]

and 和 or 的特殊性质

and 和 or 执行布尔逻辑演算,它们并不返回布尔值,而是返回它们实际进行比较的值之一。

  1. and
  • 如果布尔环境中的所有值都为真,那么 and 返回最后一个值。
  • 如果布尔环境中的某个值为假,则 and 返回第一个假值。
>>> 'a' and 'b'
'b'
>>> '' and 'b'
''
>>> 'a' and 'b' and 'c'
'c'
  • or
    • 使用 or 时,在布尔环境中从左到右演算值,就像 and 一样。如果有一个值为真,or 立刻返回该值。
    • 如果所有的值都为假,or 返回最后一个假值。
    >>> 'a' or 'b' (1)
    'a'
    >>> '' or 'b' (2)
    'b'
    >>> '' or [] or {} (3)
    {}
    >>> def sidefx():
    ... print "in sidefx()"
    ... return 1
    >>> 'a' or sidefx() (4)
    'a'
    

你可能感兴趣的:(Dive into Python Chapter4)