23 5月 2010

[頓悟] "self" 是什麼?

了 Bash script 外,我還分別去坊間的補習班學了 Java 和自己依網路文件學了 Python 兩種程式語言。 乍看之下會覺得 Bash script 的功能很強大!不過那其實只是一些簡單的演算法配合作業系統中已經安裝好的程式所達成的效果,同一支 script ,換一部電腦,可能就跑不起來了。 Java 也很強大!但是…我就是很不喜歡用一堆「大大小小的括號」來寫程式…依稀記得是創意工廠 MIT 這本書裡的一個段落提到的,某些 MIT 的學生把這樣的程式語言課程稱為「一堆陰險的笨括弧」…

而其實,我也曾因為少加了一個大括號,在 Java 的程式碼中花了三個禮拜除錯。和上述的兩種程式方式相較之下,我喜歡 "Python" 這套程式語言!

它的簡潔、規律以及利用 tab 定位鍵做為分段的設計,讓每段程式少了很多很多的括號之外,讀起來容易多了…幾乎快和看報紙一樣輕鬆了。

但即使如此,在這個程式語言中,有一個觀念我一直無法很正確地掌握…沒錯,正是所有 OOP (物件導向型程式設計) 會遇到的 "self" (或是 Java 中的 "this.") 這個觀念!

什麼是 "self" ?這個問題可能乍看之下真是「哲味十足」!難道我要問「什麼是「自我」嗎?大一時的第一堂課,授課的老師就期許我們能以蘇格拉底的 "Know thyself"("know yourself" 「認識自我」的古英文) 做為人生的目標。

那如果我現在只想 "know the self in pythn" ,我又該去向誰請教咧?蘇格拉底嗎?還是那隻過馬路的雞呢?

雖然這部份的疑惑沒有解開,但是還是開始動手寫程式。這一年來也陸陸續續完成了兩大一小共三個程式的核心部份…但是這個問題還是一直在心頭纏繞不去,就像出國了以後,才想起房間裡有垃圾忘了倒,結果每天都有一種「不痛快」的感覺…

這幾個月裡,接著看完了 MIT 的 OCW 的 Python 課程 ( 14.6 節),又看了 Python 官方網頁的教學,看著看著,我還是不懂 "self" 以及和這個「自我」伴隨出現的 "__init__" 到底是有什麼關係呢?

終於,頓悟的那天來到。(每次遇到一下子解不開的問題,我都會很用力地把問題從頭到尾想一遍,然後就放在一邊。表現上看起來像是不再理會了,但實際上我的腦子裡就會有一個角落無時不刻都在嚐試解開這個疑團!如果要形容的話,頓悟的感覺就像撞火車…或是被火車撞?兩者之間有什麼差異,我不是很確定,畢竟…這種實驗只能做一次,而且又很難設計實驗的方式…)

雖然上述的 MIT OCW 、Python 官網…舉的例子都差不多,但是不知怎麼地,看到這個教學網頁的例子時,我突然想通了。用下面的例子說明的話,就是…class Person:
     def __init__(self, name):
         self.who = name
假設有個物件,叫 "Person" ,那麼,這個物件 Person 出生的時候 (__init__ 的時候) 每次問起自己是誰 (self.who) ,我都用他的名字 (name) 回答他。

所以,假設有另一個方法叫做 DishWashing ,專門用來決定誰要洗碗的,那麼它就可以利用 Person 的「自我」,變成:
     def DishWashing(self):
         print self.who, "要洗碗"
這麼一來,只要讓 someone = Person('Peter'),這麼一來,就能讓 Peter 這個人,代稱為 someone。 再接用 someon.DishWashing() 的方式來問「誰要洗碗啊?」就可以得到 "Peter 要洗碗" 的結果了!

也就是說, 只要在 __init__ 裡定義好的 self.XXX ,其它每一段方法都能利用 self.XXX 的方式來呼叫在 __init__ 方法裡定義好的東西。

這麼一來,就不用把所有的代數定義都寫在程式的開頭部份了!只要把這些代數放在該 class 的 __init__ 方法裡,就能在同一個 class 裡面自由的呼叫了!

把以上所說的都弄成一張圖來表示的話,就是:
是不是這樣說的啊?

2 則留言:

  1. Hi ~Yen~ ,

    謝謝您提供的資料,非常有參考價值。:)

    Peter. w

    回覆刪除