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

缺省地,程序輸出進(jìn)行了格式化處理,以使其易于閱讀。多行 doc string 被合
并到單行中,要改變這個(gè)選項(xiàng)需要指定 collapse 參數(shù)的值為 0。如果函數(shù)名稱
長于 10 個(gè)字符,你可以將 spacing 參數(shù)的值指定為更大的值以使輸出更容易閱
讀。

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.

可選參數(shù)

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

spacing 和 collapse 是可選參數(shù),因?yàn)樗鼈円呀?jīng)定義了缺省值。object 是必備參數(shù),因?yàn)樗鼪]有指定缺省值。

命名參數(shù)

在 Python 中,參數(shù)可以通過名稱以任意順序指定。

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

使用內(nèi)置函數(shù) type, str, dir

  1. type函數(shù)
>>> type(1) (1)
<type 'int'>
>>> li = []
>>> type(li) (2)
<type 'list'>
>>> import odbchelper
>>> type(odbchelper) (3)
<type 'module'>
>>> import types (4)
>>> type(odbchelper) == types.ModuleType
True
  • 整型、字符串、列表、字典、元組、函數(shù)、類、模塊,甚至類
    型對象都可以作為參數(shù)被 type 函數(shù)接受
  • 可以使用 types 模塊中的常量來進(jìn)行對象類型的比較
  • str函數(shù)
    str 將數(shù)據(jù)強(qiáng)制轉(zhuǎn)換為字符串。每種數(shù)據(jù)類型都可以強(qiáng)制轉(zhuǎn)換為字符串
>>> 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)
"<module 'odbchelper' from 'c:\\docbook\\dip\\py\\odbchelper.py'>"
>>> str(None) (4)
'None'
  • dir函數(shù)
    dir 函數(shù)返回任意對象的屬性和方法列表,包括模塊對象、函數(shù)對象、字符串對象、列表對象、字典對象 ……
>>> 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函數(shù)
    它接收任何對象作為參數(shù),如果參數(shù)對象是可調(diào)用的,返回 True;否則返回 False。可調(diào)用對象包括函數(shù)、類方法,甚至類自身。
>>> import string
>>> string.punctuation (1)
'!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
>>> string.join (2)
<function join at 00C55A7C>
>>> callable(string.punctuation) (3)
False
>>> callable(string.join) (4)
True

通過getattr獲取對象引用

使用 getattr 函數(shù),可以得到一個(gè)直到運(yùn)行時(shí)才知道名稱的函數(shù)的引用。

>>> li = ["Larry", "Curly"]
>>> li.pop (1)
<built-in method pop of list object at 010DF884>
>>> getattr(li, "pop") (2)
<built-in method pop of list object at 010DF884>
>>> getattr(li, "append")("Moe") (3)
>>> li
["Larry", "Curly", "Moe"]
>>> getattr({}, "clear") (4)
<built-in method clear of dictionary object at 00F113D4>

用于模塊的getattr

>>> import odbchelper
>>> odbchelper.buildConnectionString (1)
<function buildConnectionString at 00D18DD4>
>>> getattr(odbchelper, "buildConnectionString") (2)
<function buildConnectionString at 00D18DD4>
>>> object = odbchelper
>>> method = "buildConnectionString"
>>> getattr(object, method) (3)
<function buildConnectionString at 00D18DD4>
>>> type(getattr(object, method)) (4)
<type 'function'>
>>> import types
>>> type(getattr(object, method)) == types.FunctionType
True
>>> callable(getattr(object, method)) (5)
True

使用getattr創(chuàng)建分發(fā)者

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

如果用戶傳入一個(gè)格式參數(shù),但是在 statsout 中沒有定義相應(yīng)的格式輸出函數(shù),會發(fā)生什么呢?還好,getattr 會返回 None,它會取代一個(gè)有效函數(shù)并被賦值給 output_function,然后下一行調(diào)用函數(shù)的語句將會失敗并拋出一個(gè)異常。這種方式不好。值得慶幸的是,getattr 能夠使用可選的第三個(gè)參數(shù),一個(gè)缺省返回值。

getattr缺省值

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

這個(gè)函數(shù)調(diào)用一定可以工作,因?yàn)槟阍谡{(diào)用 getattr 時(shí)添加了第三個(gè)參數(shù)。第三個(gè)參數(shù)是一個(gè)缺省返回值,如果第二個(gè)參數(shù)指定的屬性或者方法沒能找到,則將返回這個(gè)缺省返回值。

過濾列表

語法
[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 的特殊性質(zhì)

and 和 or 執(zhí)行布爾邏輯演算,它們并不返回布爾值,而是返回它們實(shí)際進(jìn)行比較的值之一。

  1. and
  • 如果布爾環(huán)境中的所有值都為真,那么 and 返回最后一個(gè)值。
  • 如果布爾環(huán)境中的某個(gè)值為假,則 and 返回第一個(gè)假值。
>>> 'a' and 'b'
'b'
>>> '' and 'b'
''
>>> 'a' and 'b' and 'c'
'c'
  • or
    • 使用 or 時(shí),在布爾環(huán)境中從左到右演算值,就像 and 一樣。如果有一個(gè)值為真,or 立刻返回該值。
    • 如果所有的值都為假,or 返回最后一個(gè)假值。
    >>> 'a' or 'b' (1)
    'a'
    >>> '' or 'b' (2)
    'b'
    >>> '' or [] or {} (3)
    {}
    >>> def sidefx():
    ... print "in sidefx()"
    ... return 1
    >>> 'a' or sidefx() (4)
    'a'
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,321評論 6 543
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,559評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,442評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,835評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,581評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,922評論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,931評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,096評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,639評論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,374評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,591評論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,104評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,789評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,196評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,524評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,322評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,554評論 2 379

推薦閱讀更多精彩內(nèi)容