1. 程式人生 > >深入理解Python(四)

深入理解Python(四)

自省

自省,是指程式碼可以檢視記憶體中以物件形式存在的其它模組和函式,獲取它們的資訊,並對它們進行操作。

可選引數和命名引數

def idol(name,age=27,sex=male):
    pass

在上述程式碼中,age和sex是可選引數,name是必備引數,但仍可以採用命名引數形式出現

In: idol(name='Luhan')
In: idol('MaYun',age=45)
In: idol(age=45,name='MaYun')

引數有如此靈活性的原因是引數本身其實是一個字典,Python按照函式宣告中定義的引數順序將引數值和引數名稱匹配起來。

內建函式

type

In: type([])
Out: <type 'list'>
In: import types
In: type([]) == types.ModuleType
Out: False
  • type函式可以接受任何東西作為引數
  • 可以用types模組中的常量進行物件型別比較

str

str函式將資料強制轉換為字串

callable

接受任何物件作為引數,如果物件可呼叫,返回True;否則False

python是自文件化的

getattr

In: li = ['a','b','c']
In: li.pop
Out: <built-in
method pop of list object at 0x000001E24149A188> In: getattr(li,"pop") Out: <built-in method pop of list object at 0x000001E24149A188>#返回呼叫的函式資訊 In: getattr(li,"append")("d") In: li Out: ['a', 'b', 'c', 'd']
  • getattr可以返回任何物件的任何屬性
  • 如果getattr返回值是方法,然後你就可以直接呼叫它
  • getattr可以作為一個分發者
import statsout

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

這樣就給函式提供了靈活性。

剛剛的示例有一個bug,即字串和函式之間存在鬆耦合,且沒有錯誤檢查。如果使用者傳入一個格式引數,但是statsout中沒有響應的格式輸出函式,會發生什麼呢?getattr會返回None,會取代一個有效函式並被賦值給output_function,然後下一行呼叫函式的語句將會失敗並丟擲一個異常,這種方式不好。

  • 慶幸的是,getattr能夠使用可選的第三個引數,一個預設返回值
import statsout

def idol(data, format = "text"):
    output_function = getattr(statsout, "output_%s" % format,statsout.output_text)
    return output_function(data)
  • 如果第二個引數指定的屬性或方法沒能找到,則將返回這個預設返回值

count方法與排除重複元素

In: li = ['a','b','c','a']
In: [elem for elem in li if li.count(elem) == 1]
Out: ['b','c']#返回原始列表中僅出現一次的元素的拷貝值的列表

這種方法不能用於排除重複元素

and和 or

  • and 和 or 並不返回布林值,只返回它們實際進行比較的值之一
In: 'a' and 'b'
Out: 'b'
#and在布林環境中從左到右演算表示式的值
#如果布林環境中所有值為真,and返回最後一個值
In: '' and 'b'
Out: ''
#布林環境中'',[],{},(),None均為假
#and返回第一個假值

In: 'a' or 'b'
Out: 'a'
#or在布林環境中從左到右演算表示式的值
#如果布林環境中有一個值為真,返回第一個真值
In: '' or {} or []
Out:[]
#如果布林環境中所有值為假,返回最後一個假值
  • 使用and和or完成if判定
  • 在C++中,有一種選擇條件句
bool?a:b

如果bool為真返回a,否則返回b
Python中有相似的技巧

In: a=""
In: b="second"
In: (1 and [a] or [b])[0]

在某種情況下if語句是不允許使用的,比如lambda函式中,這樣我們就可以用上述方法代替if語句。

lambda函式

In: (lambda x:x*2)(3)
Out: 6
  • 引數列表周圍沒有括號,且忽略了return關鍵字,可以將其賦值給變數使用
  • lambda函式可以接受任意多個引數(包括可選引數)並返回單個表示式的值
  • lambda函式物件在布林環境中總是為真
processFunc = collapse and (lambda s:" ".join(s.split())) or (lambda s:s)

續行

  • 續行符()分割多行
  • 一些表示式可以分割成多行,不需要使用反斜線。例如:列表、元組、字典。

ljust

In: s = 'iiiiiii'
In: s.ljust(30)
Out: 'iiiiiii                       '
#返回一個新的拷貝,用空格填充字串
#若指定長度小於字串長度,ljust簡單地返回未變化的字串。它不會截斷字串。