Dive Into Python 学习记录2-自省/info 函数 /str / type /callable 函数

来源:互联网 发布:sybase数据库备份恢复 编辑:程序博客网 时间:2024/05/22 07:04

2.1 自省

自省是指代码可以查看内存中以对象形式存在的其它模块和函数,获取它们的信息,并对它们进行操作。用这种方法,你可以定义没有名称的函数,不按函数声明的参数顺序调用函数,甚至引用事先并不知道名称的函数。

def info(object, spacing=10, collapse=1): 1 2 3    #多行 doc string 被合并到单行中,要改变这个选项需要指定 collapse 参数的值为 0。                                                               #如果函数名称长于10个字符,你可以将 spacing 参数的值指定为更大的值以使输出更容易阅读    """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__":                4 5    print info.__doc__
1该模块有一个声明为 info 的函数。根据它的函数声明可知,它有三个参数:objectspacingcollapse。实际上后面两个参数都是可选参数,关于这点你很快就会看到。2info 函数有一个多行的 doc string,简要地描述了函数的功能。注意这里并没有提到返回值;单独使用这个函数只是为了这个函数产生的效果,并不是为了它的返回值。3函数内的代码是缩进形式的。4if__name__ 技巧允许这个程序在自己独立运行时做些有用的事情,同时又不妨碍作为其它程序的模块使用。在这个例子中,程序只是简单地打印出 info 函数的 doc string5if 语句使用== 进行比较,而且不需要括号。

info 函数的设计意图是提供给工作在 PythonIDE 中的开发人员使用,它可以接受任何含有函数或者方法的对象 (比如模块,含有函数,又比如list,含有方法) 作为参数,并打印出对象的所有函数和它们的doc string

info 函数就是这样一个例子,它有两个可选参数。

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

spacingcollapse 是可选参数,因为它们已经定义了缺省值。object 是必备参数,因为它没有指定缺省值。如果调用info 时只指定一个参数,那么 spacing 缺省为 10collapse 缺省为 1。如果调用 info 时指定两个参数,collapse 依然默认为 1

假如你要指定 collapse 的值,但是又想要接受 spacing 的缺省值。在绝大部分语言中,你可能运气就不太好了,因为你需要使用三个参数来调用函数,这势必要重新指定spacing 的值。但是在 Python 中,参数可以通过名称以任意顺序指定。


举例:对一个list查找可以进行相关操作的函数

>>> from apihelper import info
>>> li = [ ]
>>> info(li)
__add__    x.__add__(y) <==> x+y
__class__  list() -> new empty list list(iterable) -> new list initialized from iterable's items
__contains__ x.__contains__(y) <==> y in x
__delattr__ x.__delattr__('name') <==> del x.name
__delitem__ x.__delitem__(y) <==> del x[y]
__delslice__ x.__delslice__(i, j) <==> del x[i:j] Use of negative indices is not supported.
__eq__     x.__eq__(y) <==> x==y
__format__ default object formatter
__ge__     x.__ge__(y) <==> x>=y
__getattribute__ x.__getattribute__('name') <==> x.name
__getitem__ x.__getitem__(y) <==> x[y]
__getslice__ x.__getslice__(i, j) <==> x[i:j] Use of negative indices is not supported.
__gt__     x.__gt__(y) <==> x>y
__iadd__   x.__iadd__(y) <==> x+=y
__imul__   x.__imul__(y) <==> x*=y
__init__   x.__init__(...) initializes x; see help(type(x)) for signature
__iter__   x.__iter__() <==> iter(x)
__le__     x.__le__(y) <==> x<=y
__len__    x.__len__() <==> len(x)
__lt__     x.__lt__(y) <==> x<y
__mul__    x.__mul__(n) <==> x*n
__ne__     x.__ne__(y) <==> x!=y
__new__    T.__new__(S, ...) -> a new object with type S, a subtype of T
__reduce__ helper for pickle
__reduce_ex__ helper for pickle
__repr__   x.__repr__() <==> repr(x)
__reversed__ L.__reversed__() -- return a reverse iterator over the list
__rmul__   x.__rmul__(n) <==> n*x
__setattr__ x.__setattr__('name', value) <==> x.name = value
__setitem__ x.__setitem__(i, y) <==> x[i]=y
__setslice__ x.__setslice__(i, j, y) <==> x[i:j]=y Use of negative indices is not supported.
__sizeof__ L.__sizeof__() -- size of L in memory, in bytes
__str__    x.__str__() <==> str(x)
__subclasshook__ Abstract classes can override this to customize issubclass(). This is invoked early on by abc.ABCMeta.__subclasscheck__(). It should return True, False or NotImplemented. If it returns NotImplemented, the normal algorithm is used. Otherwise, it overrides the normal algorithm (and the outcome is cached).
append     L.append(object) -- append object to end
count      L.count(value) -> integer -- return number of occurrences of value
extend     L.extend(iterable) -- extend list by appending elements from the iterable
index      L.index(value, [start, [stop]]) -> integer -- return first index of value. Raises ValueError if the value is not present.
insert     L.insert(index, object) -- insert object before index
pop        L.pop([index]) -> item -- remove and return item at index (default last). Raises IndexError if list is empty or index is out of range.
remove     L.remove(value) -- remove first occurrence of value. Raises ValueError if the value is not present.
reverse    L.reverse() -- reverse *IN PLACE*
sort       L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*; cmp(x, y) -> -1, 0, 1
>>> import odbchelper
>>> info(odbchelper)
buildConnectionString Build a connection string from a dictionary Returns string.
>>> info(odbchelper, 30, 0)
buildConnectionString          Build a connection string from a dictionary
    
    Returns string.

举例:对一个tuple查找可以进行相关操作的函数

from apihelper import info
>>> li = ()
>>> info(li)
__add__    x.__add__(y) <==> x+y
__class__  tuple() -> empty tuple tuple(iterable) -> tuple initialized from iterable's items If the argument is a tuple, the return value is the same object.
__contains__ x.__contains__(y) <==> y in x
__delattr__ x.__delattr__('name') <==> del x.name
__eq__     x.__eq__(y) <==> x==y
__format__ default object formatter
__ge__     x.__ge__(y) <==> x>=y
__getattribute__ x.__getattribute__('name') <==> x.name
__getitem__ x.__getitem__(y) <==> x[y]
__getnewargs__ None
__getslice__ x.__getslice__(i, j) <==> x[i:j] Use of negative indices is not supported.
__gt__     x.__gt__(y) <==> x>y
__hash__   x.__hash__() <==> hash(x)
__init__   x.__init__(...) initializes x; see help(type(x)) for signature
__iter__   x.__iter__() <==> iter(x)
__le__     x.__le__(y) <==> x<=y
__len__    x.__len__() <==> len(x)
__lt__     x.__lt__(y) <==> x<y
__mul__    x.__mul__(n) <==> x*n
__ne__     x.__ne__(y) <==> x!=y
__new__    T.__new__(S, ...) -> a new object with type S, a subtype of T
__reduce__ helper for pickle
__reduce_ex__ helper for pickle
__repr__   x.__repr__() <==> repr(x)
__rmul__   x.__rmul__(n) <==> n*x
__setattr__ x.__setattr__('name', value) <==> x.name = value
__sizeof__ T.__sizeof__() -- size of T in memory, in bytes
__str__    x.__str__() <==> str(x)
__subclasshook__ Abstract classes can override this to customize issubclass(). This is invoked early on by abc.ABCMeta.__subclasscheck__(). It should return True, False or NotImplemented. If it returns NotImplemented, the normal algorithm is used. Otherwise, it overrides the normal algorithm (and the outcome is cached).
count      T.count(value) -> integer -- return number of occurrences of value
index      T.index(value, [start, [stop]]) -> integer -- return first index of value. Raises ValueError if the value is not present.
>>>
2.2 type / str / dir

>>> type(1)           1<type 'int'>>>> li = []>>> type(li)          2<type 'list'>>>> import odbchelper>>> type(odbchelper)  3<type 'module'>>>> import types      4>>> type(odbchelper) == types.ModuleTypeTrue
1type 可以接收任何东西作为参数――我的意思是任何东西――并返回它的数据类型。整型、字符串、列表、字典、元组、函数、类、模块,甚至类型对象都可以作为参数被type 函数接受。2type 可以接收变量作为参数,并返回它的数据类型。3type 还可以作用于模块。4你可以使用 types 模块中的常量来进行对象类型的比较。这就是info 函数所做的,很快你就会看到。

str 将数据强制转换为字符串。每种数据类型都可以强制转换为字符串。str 还允许作用于模块;

>>> a = 123456
>>> str (a)
'123456'
>>> b = str (a)
>>> b
'123456'
>>> a
123456
>>> list = ['123', '456','789','python']
>>> list
['123', '456', '789', 'python']
>>> b = str(list)
>>> b
"['123', '456', '789', 'python']"
>>> tuple = ('123', '456','789','python')
>>> tuple
('123', '456', '789', 'python')
>>> b = str(tuple)
>>> b
"('123', '456', '789', 'python')"
>>> tuple = (123, 456,789,python)            #元组内元素python类型无法确定,报错,

Traceback (most recent call last):
  File "<pyshell#28>", line 1, in <module>
    tuple = (123, 456,789,python)
NameError: name 'python' is not defined
>>> tuple = (123, 456,789)
>>> tuple = (123, 456,789,'python' # 字符串写法,否则报未定义错误
>>> b = str(tuple)
>>> b
"(123, 456, 789, 'python')"
>>>
>>> type(tuple[0])
<type 'int'>
>>> type(tuple[3])
<type 'str'>

 tuple = (abc, der, python)              # 有此用法,但元素需要先定义

Traceback (most recent call last):
  File "<pyshell#35>", line 1, in <module>
    tuple = (abc, der, python)
NameError: name 'abc' is not defined

info 函数的核心是强大的 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']
1li 是一个列表,所以 dir(li) 返回一个包含所有列表方法的列表。注意返回的列表只包含了字符串形式的方法名称,而不是方法对象本身。2d 是一个字典,所以 dir(d) 返回字典方法的名称列表。其中至少有一个方法,keys,看起来还是挺熟悉的。3这里就是真正变得有趣的地方。odbchelper 是一个模块,所以dir(odbchelper) 返回模块中定义的所有部件的列表,包括内置的属性,例如__name____doc__,以及其它你所定义的属性和方法。在这个例子中,odbchelper 只有一个用户定义的方法,就是在第 2 章中论述的buildConnectionString 函数。

callable 函数,它接收任何对象作为参数,如果参数对象是可调用的,返回 True;否则返回 False。可调用对象包括函数、类方法,甚至类自身

>>> import string>>> string.punctuation           1'!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'>>> string.join                  2<function join at 00C55A7C>>>> callable(string.punctuation) 3False>>> callable(string.join)        4True>>> print string.join.__doc__    5join(list [,sep]) -> string    Return a string composed of the words in list, with    intervening occurrences of sep.  The default separator is a    single space.    (joinfields and join are synonymous)
1string 模块中的函数现在已经不赞成使用了 (尽管很多人现在仍然还在使用join 函数),但是在这个模块中包含了许多有用的变量,例如 string.punctuation,这个字符串包含了所有标准的标点符号字符。2string.join 是一个用于连接字符串列表的函数。3string.punctuation 是不可调用的对象;它是一个字符串。(字符串确有可调用的方法,但是字符串本身不是可调用的。)4string.join 是可调用的;这个函数可以接受两个参数。5任何可调用的对象都有 doc string。通过将 callable 函数作用于一个对象的每个属性,可以确定哪些属性 (方法、函数、类) 是你要关注的,哪些属性 (常量等等) 是你可以忽略、之前不需要知道的。









原创粉丝点击