Python讀書筆記:細節決定成敗(2)
感謝一個@一個獨行的程式設計師的投遞 來自一個獨行的程式設計師
背景:我本來是一個信奉Java大法好的程式設計師。但是最近由於工作原因,不得不開始學習python。因此,寫下這個讀書筆記,希望能起到一個拋磚引玉的作用。原文中所有引用部分均來自python官方的tutorial
8.input() vs raw_input()
他們的作用都是用來讀取命令列或者檔案中的資料,區別在於返回結果
- input()返回的是numeric,如
int,flat,double
- raw_input()返回的是
String
舉個例子:
>>> input() 12+2 #comand line input 14 #ouput >>> raw_input() 12+2 #comand line input '12+2' #ouput
然而在讀過python的原始碼後,你會發現其實input()是通過raw_input來實現的:
def input(prompt): return (eval(raw_input(prompt)))
9.Output Formating
從C語言開始,格式化字串就已經為程式設計師所熟知,不管是C/C++還是Java,我覺得都沒有python在輸出格式化方面做的這麼簡練易用。舉兩個例子:
zfill()
‘pads a numeric string on the left with zeros. It understands about plus and minus signs:‘
這個函式的厲害之處在於它不僅能夠高位補零,而且可以識別正負號!
>>> '12'.zfill(5) '00012' >>> '-3.14'.zfill(7) '-003.14'
str.format()
當有多個string需要輸出時,這個函式非常的powerful:
>>> print 'We are the {} who say "{}!"'.format('knights', 'Ni') We are the knights who say "Ni!"
with position:
>>> print '{0} and {1}'.format('spam', 'eggs') spam and eggs >>> print '{1} and {0}'.format('spam', 'eggs') eggs and spam
with keyword:
>>> print 'This {food} is {adjective}.'.format( ... food='spam', adjective='absolutely horrible') This spam is absolutely horrible.
combine position with keyword:
>>> print 'The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred', ... other='Georg') The story of Bill, Manfred, and Georg.
對於需要遍歷輸出對應項的情況,python更是給出了一個不錯的解決方案—>:
,再結合一下position和format,完美!
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678} >>> for name, phone in table.items(): ... print '{0:10} ==> {1:10d}'.format(name, phone) ... Jack ==> 4098 Dcab ==> 7678 Sjoerd ==> 4127
10.Serializing and Deserializing
序列化(serializing)和反序列化(deserializing)是為了資料的易用性而出現的,在不同開發平臺和網際網路中,資料的表示方法一直都是處於百花齊放的局面。直到JSON的出現,才有了一個便於交換(interchange)的資料格式
- 序列化: 將python中的資料結構以字串形式表示
- 反序列化: 將上述的字串重建為python中的資料結構
- JSON: JavaScript Object Notation
簡單來說,只需要記住兩個函式json.dumps()
和json.load()
就可以了。他們的函式原型分別是:
json.dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, encoding="utf-8", default=None, sort_keys=False, **kw)
兩個函式的引數意義相同,可以自行閱讀tutorial瞭解詳情,這裡不展開了。
json.load(fp[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])
11.Class Objects
python是支援OOP的語言,因此接下來幾節介紹python中到的各種物件。
類是一個抽象的概念,類物件(class objects)支援兩種操作(operations):
- 屬性引用(attribute references)
- 例項化(instantiation)
與其它大多數OOP語言一樣,python的類也有變數和方法(method),不過卻又略有不同。python的變數(data attribute)是屬於類的,也即是說只要定義了類,那麼不需要例項化,就能夠直接訪問,類似於java中類的靜態變數(static variable).並且可以直接通過賦值(assign)去修改值。舉例:
>>> class Simple: ... i = 1 ... def foo(self): ... return "hello world" ... >>> Simple.i 1 >>> Simple.i = 2 >>> Simple.i 2
但是類的方法卻必須通過例項化後才能訪問,python中的例項化也有其獨特之處,例項物件(instance object)放在下節講。如果沒有例項化而直接去訪問類中定義的方法,會報unbound method
,這是因為方法(method)是必須作用到一個實際的物件上的,而類物件本身是抽象的:
>>> Simple.foo <unbound method Simple.foo>
至於為什麼類中的方法必須要自帶一個self引數,我後面再講,這也是python作為一個動態語言,與靜態的OOP之間最大的差異!
12.Instance Objects
例項物件(instance object)是一個具體的可操作的物件,其例項化的過程在python的官方解釋中是這麼說明的:
“Class instantiation uses function notation. Just pretend that the class object is a parameterless function that returns a new instance of the class.“
官方讓我們假設類物件是返回一個例項物件的無參函式,所以例項化的過程就像是得到一個函式的返回結果。(暈嗎?)個人感覺按照C++和Java的構造器(constructor)來理解,也不會出現太大問題。
>>> x = Simple() >>> x.foo() 'hello world'
既然要例項化,必然躲不過一個詞“初始化”(initialization),python中定義了__init()__
這個方法來初始化例項物件。舉個例子:
>>> class A: ... i = 1 ... def __init__(self): ... self.i = 3 ... >>> >>> A.i 1 #class attribute >>> x = A() >>> x.i 3 #instance attribute >>> A.i 1 #class attribute
前面我做了比喻,類的變數和Java中的靜態變數類似,但這裡可以看出它們的不同。在Java中靜態變數是屬於類的,被其所有例項共用。然而python的變數不是共用的,所以我才說python的類理解起來更抽象一點,類也是一個物件,不過和例項物件卻不同,更加抽象(暈嗎?)
之所以有這麼大的差異,主要原因是python是一個動態語言,它可以動態新增屬性,這就令很多一直用Java和C++的人不習慣。不過當你習慣之後,你會發覺它這種設計也真是好處多多。比如,你可以隨時給你的類增加新的變數啊~
>>> class A: ... i = 1 ... >>> A.j = 2 >>> A.j 2
13.Method Objects
在python中,方法(method)和函式(function)是不同的。方法應該特指在類中定義的,其特徵就是在定義時必須帶上一個引數self
。這和其他語言隱式的處理this
這個引數不同(兩者作用一樣)。python必須要顯示的指定這個方法作用的物件,這樣的好處是在呼叫時能夠確保方法是繫結(bound)在作用物件上的。因此,類是不能憑空呼叫方法的,必須作用在例項上才行,所以前面章節的例子裡會出現unbound method
這個錯誤提示。舉個例子:
>>> class B: ... def f(self): ... return "Hello Method" ... >>> b = B() #b is an instance object >>> b.f() 'Hello Method'he >>> B.f(b) #B is a class object 'Hello Method'
當類B有了例項b之後,它也是可以呼叫方法f的,因為這一切都只是為了確保這個方法的作用物件是存在的!現在回過頭來看self
,其實就是指類的例項本身作為引數傳進這個函式:
“the special thing about methods is that the object is passed as the first argument of the function.“
這樣也就好解釋為什麼函式本身定義時是可以不用顯示的寫self
引數了,因為函式本身可以不屬於任何類。如果有學過pascal這類程式導向的語言,就很好理解這句話了。
>>> def f(): #Void, like a procedure in pascal ... 1 + 2 ... >>> f() >>> def ff(): #Return, like a function in pascal ... return 1 + 2 ... >>> ff() 3
相關文章
- Python讀書筆記:細節決定成敗(1)Python筆記
- 開發者談F2P模式:細節決定成敗模式
- 細節決定成敗——無CSS時網頁的可讀性CSS網頁
- 面試:黃金法則——細節決定成敗面試
- 一個MapReduce 程式示例 細節決定成敗(一)
- 細節決定成敗!APP設計不容忽視的20個細節APP
- Java集合詳解8:Java集合類細節精講,細節決定成敗Java
- 邦芒簡歷:求職簡歷細節決定成敗求職
- 細節決定成敗 MapReduce任務實戰 Map Join
- 細節決定成敗 MapReduce任務實戰 Reduce Join
- 細節決定成敗 MapReduce任務實戰 倒排索引索引
- 一個MapReduce 程式示例 細節決定成敗(五) :Partitioner
- 第五章 Vlookup函式示例-細節決定成敗函式
- 汪峰FIIL Diva智慧耳機究竟如何?細節決定成敗
- 如何讓程式設計師幸福工作:細節決定成敗程式設計師
- 細節決定ERP專案啟動會的成敗
- 一個MapReduce 程式示例 細節決定成敗(九):RawComparator
- 一個MapReduce 程式示例 細節決定成敗(八):TotalOrderPartitioner
- java併發變成實戰讀書筆記(1,2章節)Java筆記
- 細節決定成敗,不容忽視的10道Node面試題面試題
- 一個MapReduce 程式示例 細節決定成敗(六) :CombineFileInputFormatORM
- 一個MapReduce 程式示例 細節決定成敗(三) :Combiner
- 軟體設計是怎樣煉成的(7)——細節決定成敗(詳細設計)
- 讀書筆記2筆記
- MySQL 8.0 Reference Manual(讀書筆記91節--Replication(2))MySql筆記
- FPGA讀書筆記2FPGA筆記
- 一個MapReduce 程式示例 細節決定成敗(二) :觀察日誌及 Counter
- MySQL 8.0 Reference Manual(讀書筆記40節-- Data Types(2))MySql筆記
- MySQL 8.0 Reference Manual(讀書筆記55節--Optimization and Indexes(2))MySql筆記Index
- fluent python 讀書筆記 2–Python的序列型別2Python筆記型別
- 一個MapReduce 程式示例 細節決定成敗(七) :自定義Key 及RecordReader
- Effective Java 讀書筆記(2)Java筆記
- 讀書筆記【2】 初探Storyboard筆記
- 讀書筆記(2)《微精通》筆記
- MySQL 8.0 Reference Manual(讀書筆記76節--Optimizer Statistics for InnoDB (2))MySql筆記
- MySQL 8.0 Reference Manual(讀書筆記35節-- 字元編碼(2))MySql筆記字元
- 《決斷力》讀書筆記筆記
- 《小決心》讀書筆記筆記