高見龍

iOS app/Ruby/Rails Developer & Instructor, 喜愛非主流的新玩具 :)

Boolean

Boolean? 真的假的?

Boolean值很單純,只有兩種結果,就是真的(True)跟假的(False),不是真的就是假的,沒有灰色地帶。

哪些東西是假的?

  • 0 數字0
  • ”” 空字串
  • [] 空的List
  • () 空的Tuple
  • {} 空的Dict
  • None
  • 當然還有False本身也是假的..

因為真的(True)太多種,沒辦法用窮舉法一項一項列出來,所以我們只要記得哪些是假的(False),然後只要不是假的,就是真的。

要注意的是,在Python,程式碼是有大小寫之分的,所以如果寫成false的話,是認不出來的。

接下來,我們來看看很常使用的字串..

數字

沒有上限?

在Python,數字基本上是沒有上限的。也不是說沒有沒有上限,就用到電腦記憶體用完為止。有些程式語言的數字的值都有一個限制,超過就會發生溢位(overflow)。什麼是溢位? 就像你車子的里程表,假設全部有6個位數,也就是最大顯示是999999,但只要超過這個數字就會從000000開始,在處理資料的時候,這通常不會是你想要的結果。而Python沒有這個問題,也就是因為這樣,Python可以拿來算很大的數字都是ok的。

數字裡面,只要有小數點就會被視為浮點數,而浮點數會有誤差,例如:

1
print 0.1 + 0.1 + 0.1 - 0.3

算出來的結果應該跟我們人類的腦袋不太一樣。如果你有這方面的需求,可以藉助Decimal模組的幫忙:

>>> from decimal import *
>>> Decimal('0.1') + Decimal('0.1') + Decimal('0.1') - Decimal('0.3')
Decimal('0.0')

這樣算出來應該就會是你要的了。

四則運算

基本上跟我們在小學時候學的差不多,就加+、減-、乘*、除/,先乘除後加減,如果遇到括號要先處理。這些都差不多,不過"除法"比較不一樣一點,如果除數跟被除數都是整數的話,那算出來的結果就會是整數,例如:

print 10/3     # 3

如果你在除數或被除數其中一個加上小數點,讓它變成浮點數型態的話,算出來就又不一樣了:

print 10.0/3   # 3.333333333

但如果你想要強迫進行整數除法的話,請使用//

print 10.0//3  # 3.0

次方則是使用**

print 2**3     # 8

型態轉換可使用int()float()complex()等方法來把原來的數字轉換成整數、浮點數以及複數型態。

再來,我們來看看Python的Boolean型態..

Method

為什麼要寫method?

程式碼就這樣一行一行的寫不好嗎? 當你的程式碼超過一定的行數的時候,一行一行的寫就不會是個好的寫法。通常我們會用一個抽象的名詞,來把一群連續或複合的動作給包在一起,這樣一來程式碼變得有系統了,心情也會變得比較好,重點是,會寫method,就容易會有種變成高手的錯覺!

雖然這也許是玩笑話,但把程式碼整理到method裡,程式碼會變得比較好維護,而且也更容易可以重複使用。

定義

method定義
1
2
3
4
5
6
7
8
def calc_method(a, b = 1):
  print a * b

def args_method(*args):
  print args

def kwargs_method(**kwargs):
  print kwargs

第1行的calc_method比較容易懂,這個method會接收2個參數,其中一個還是有預設值的;第4行的args_method後面的參數加了一顆*,表示傳進去的參數args會被集中成一個Tuple;而第7行的kwargs_method則會把傳進去的參數kwargs集中成一個Dictionary。

pass!! 什麼都不做..?

前面提到Python的程式是靠縮排來區分code block的,不過如果我們寫了一個method,但裡面目前還沒想到要寫什麼,或是在if..else..的判斷裡面暫時還沒想到要寫什麼內容,如果就這樣空的不理它是不行的,這時候你就需要pass這個什麼事都不做的東西,像這樣:

1
2
def do_something():
  pass

或是像這樣:

1
2
3
4
if age >= 18:
  pass
else:
  print "kid, go back to school!"

這個pass的用途,就是只放個包包佔位置而已,其它什麼事都不做。也許你會覺得很不習慣,不過這個應該只有像在Python這種依賴縮排的程式語言才看得到的特色(?)吧。

呼叫/使用

呼叫/使用
1
2
3
4
5
6
calc_method(4)
calc_method(4, 10)
calc_method(b = 10, a = 2)

args_method(1, 2, 3)
kwargs_method(name = "eddie", age = 20)

Python的method呼叫是透過小括號(),並且可以在裡面傳參數進去,不過Python的參數還滿自由的,不一定要照著順序傳進去,像是上面這段程式碼的第3行,只要知道變數名稱,用這種方式傳也是行得通的。

回傳值

每個method執行結束,可以使用return關鍵字來指定要回傳的值,如果沒有特別指定,則回傳值是None(相當於在別的程式語言的NullNil)。所以這段程式碼的的回傳值:

1
2
3
4
def calc_method(a, b = 1):
  print a * b

print calc_method(10)

因為calc_method最後並沒明確的指示要回傳什麼值,所以上面這段程式碼的執行結果,會得到在calc_method裡印出的結果10,以及用print把回傳值None給印出來。

Lambda? 黏巴達?

Lambda
1
2
my_profile = lambda user_name, age : "%s is %i years old" % (user_name, age)
print my_profile("eddie", 30)

lambda其實就是一種匿名(anonymous)的method,它不用像一般method使用def來事先定義好。

Method Decorator

decorator的意思簡單的說,就是用某個method把你原來的method給包起來,也就是你在執行內層method之前,會先執行外層的method。這個在Python或Django的程式碼還滿常見的,主要有兩種方式來實作:

第一種是使用method來做decorator:

method decorator
1
2
3
4
5
6
7
8
9
10
11
def my_deco(func_name):
  print "Hello, this is method decorator"
  def wrapper():
    return func_name
  return wrapper

@my_deco
def real_method():
  print "This is real method"

real_method()

另一種是使用類別來做decorator:

method decorator
1
2
3
4
5
6
7
8
9
10
11
12
13
class Deco(object):
  def __init__(self, func_name):
    self.func_name = func_name

  def __call__(self, *args):
    print "This is a decorator class"
    return self.func_name(*args)

@Deco
def real_method():
  print "This is real method"

real_method()

接下來,我們來看看在Python裡面的一些基本的資料型態.. 數字!

邏輯及流程控制

變數

在開始講流程控制之前,要先來看一下在Python的變數。

Pytho的變數有幾項特點以及有趣的使用:

  • 不用宣告,可以直接用 x = “abc”
  • 變數名稱沒有型態
  • x, y, z = 1, 2, 3 可一口氣指定多個變數
  • x, y = y, x 把x跟y的值對調
  • x, y, z = “abc” 會得到x = “a”, y = “b”, z = “c”
  • x = y = z = “abc” x、y、z都是"abc"

命名規範

  1. 最好取有意義且相關的
  2. 開頭只能以底線或英文字母
  3. 小心保留字

保留字:

and as assert break class continue def
del elif else except exec finally for
from global if import in is lambda
not or pass print raise return try
while with yield

如果這樣,那就這樣,不然就那樣.. 的if-else

所謂的邏輯控制,說穿了大概就是「如果下雨,就去吃麥當勞,不然就去吃肯德雞」之類的敘述罷了。如果我們把這段語法改寫成程式碼的話:

1
2
3
4
5
6
weather = "sunny"

if weather == 'rainy':
  print "go to M"
else:
  print "go to KFC"

如果你曾經學過別的程式語言,例如C/C++/PHP,你可能一下子看到這樣的程式碼會不太習慣。Python的code block不需要大括號,只要用整齊的縮排就可以了。至於你是要縮排2格空白、4格空白都可以,只要排整齊就好了。另外,每行的行末也不需要分號做為結束。

Python的變數不需要特別宣告,在做邏輯判斷的時候,如果不會影響語意的話,也是不需要小括號的。假設我們原來這段程式碼改用C-like的程式碼來改寫的話,可能會長得像這樣:

1
2
3
4
5
6
7
var weather:String = "sunny";

if (weather == "rainy"){
  print("go to M");
}else{
  print("go to KFC");
}

上面這段程式碼只是舉例,不一定完全正確。不過要表達一樣的意思,用Python就是可以讓你的程式碼變得簡單很多,至少你可以少敲好幾下鍵盤,也因為Python的程式碼強制一定要縮排排整齊,所以你也不用擔心程式碼風格會差很多的問題(當然有的人就是喜歡用奇技淫巧..硬是要寫得跟別人不同的也大有人在)。

if..else..,那當然也要來一下elseif之類的語法,不過Python的elseif是用elif

1
2
3
4
5
6
7
8
9
10
weather = "sunny"

if weather == 'rainy':
  print "M"

elif weather == 'not good':
  print "Stay at home"

else:
  print "KFC"

switch?

你知道當程式的判斷開始越來越多的時候,學校老師或是教課書上就會教我們用switch之類的語法來處理,不過,你可能會很訝異,Python沒有swtich之類的語法的,它就是用一大串的if..elif..else..來處理。

不優美嗎? 我覺得還好。反正Python程式碼的縮排很清楚,看起來也不會多混亂 :)

註解

Python的註解有兩種,單行註解跟多行註解。單行的這樣用:

1
# this is comment in python

多行的這樣用

1
2
3
4
5
"""
this is comment
this is comment, too!
many comment..
"""

中文字..會出現錯誤!!

如果你的檔案裡有用到非英文字元的話,請在檔案最前面加上一行:

# encoding: utf-8

這樣你的程式執行起來才不會跳出SyntaxError,誰叫電腦跟程式語言不是中國人發明的..

輸入/輸出

這個我們在寫一些console的應用程式的時候常會用到,前面我們已經用過print了,不過接下來我們來試著做個可以跟使用者互動的簡單小程式:

1
2
3
4
5
6
print "Hello, how old are you?"
age = raw_input()
if age >= 18:
  print "You're an Adult already!"
else:
  print "kid, go back to school!"

這其實也是個沒什麼實戰用途的程式碼範例,也沒有很嚴格的檢查輸入值的範圍,不過可以從這邊看到在Python的輸入/輸出大概是怎麼處理的。另外一樣在處理輸入的,還有兩個稍微要提的,分別是raw_inputget_pass模組。也許你會好奇inputraw_input的差別? 比較明顯的差別是在於數字的處理,如果你輸入20+3,你會得到23,但如果用的是raw_input的話,則是得到20+3這個字串。

不管是input或是raw_input,我們在輸入的過程中都會被旁邊的人看光光,如果你不想你在輸入密碼的時候全部都秀在畫面上,你可以使用get_pass這個內建的模組。我們直接在shell裡試試看:

>>> import getpass
>>> getpass.getuser()
>>> your_pw = getpass.getpass("please input your password: ")
please input your password:

這樣你打的字就應該不會被看到了。

接下來,我們要來把這些程式碼包成method(方法)..

如果你是使用Windows作業系統的話..

在Windows安裝Python很難嗎?

就安裝的話,一點都不難,因為Python已經有幫Windows做好安裝檔了,檔案下載回來之後點一點、下一步的按鈕按一按差不多就搞定了。

其實在Windows上寫Python,Python本身沒什麼問題,倒是環境比較痛苦。特別是之後的Django,它的懶人安裝包(Instant Django)專案也已經消失了,在Windows上練習寫Django的麻煩度就又增加了..

有比較完美的解決方法嗎?

最完美的解決方法就是 - 不要用Windows,不過我想那對正在用Windows的人來還滿困難的。

如果你因為工作或是其它因素不得不用它,那也許可以考慮安裝雙系統,或是像VirtualBox在Windows上模擬Linux的作業環境。我之前試過VirtualBox的這個解決方案,其實還滿完美的,之前在中研院OpenFoundry的工作坊講課的時候就是用它搭配Ubuntu,還滿ok的,但可惜就是速度會慢了點,遇到硬體設備比較差的電腦跑起來會有點辛苦。

如果你不想重灌或安裝VirtualBox,我自己試了一下,大概安裝Cygwin是比較簡單的解決方法了。

Cygwin的官網一進去就看到"Get that Linux feeling - on Windows!“,雖然離真正的Linux還是有點距離,但光是這個feeling,大概就可以讓我們在上面練習Python跟Django了。

在安裝Cygwin的過程中,請順便勾選Pythonwget這兩個工具選項,在安裝Cygwin的過程中也會一併把這些工具一起裝進Cygwin的系統裡。

它所有的軟體都會安裝在Cygwin自己的資料夾裡,所以如果你不要用的話,整個資料夾砍掉就行了。

安裝完Cygwin之後,因為我們可能從Windows貼一些指令到Cygwin,如果你發現你的Cygwin沒辦法接受滑鼠右鍵貼上的話,請改一下視窗的設定:

在視窗的上面按一下滑鼠右鍵,選擇「內容」:

image

把「快速編輯模式」打勾:

image

這樣就搞定了!

編輯器呢?

雖然說Python程式碼用記事本就可以寫了沒錯,但因為記事本功能太陽春,通常那是最不得已才會開它起來改程式。我想現在文字編輯器的牌子不少,每款軟體用起來的手感也不太一樣,大家可以多比較看看哪些編輯器。如果你懶得比較,那就直接抓Notepad++來用吧,至少它該有的程式碼顏色功能都有了。