十分鐘學會 Python

Stavros Korokithakis發表於2015-09-30

初試牛刀

假設你希望學習Python這門語言,卻苦於找不到一個簡短而全面的入門教程。那麼本教程將花費十分鐘的時間帶你走入Python的大門。本文的內容介於教程(Toturial)和速查手冊(CheatSheet)之間,因此只會包含一些基本概念。很顯然,如果你希望真正學好一門語言,你還是需要親自動手實踐的。在此,我會假定你已經有了一定的程式設計基礎,因此我會跳過大部分非Python語言的相關內容。本文將高亮顯示重要的關鍵字,以便你可以很容易看到它們。另外需要注意的是,由於本教程篇幅有限,有很多內容我會直接使用程式碼來說明加以少許註釋。

Python的語言特性

Python是一門具有強型別(即變數型別是強制要求的)、動態性、隱式型別(不需要做變數宣告)、大小寫敏感(var和VAR代表了不同的變數)以及物件導向(一切皆為物件)等特點的程式語言。 

獲取幫助

你可以很容易的透過Python直譯器獲取幫助。如果你想知道一個物件(object)是如何工作的,那麼你所需要做的就是呼叫help(<object>)!另外還有一些有用的方法,dir()會顯示該物件的所有方法,還有<object>.__doc__會顯示其文件:

>>> help(5)
Help on int object:
(etc etc)

>>> dir(5)
['__abs__', '__add__', ...]

>>> abs.__doc__
'abs(number) -> number

Return the absolute value of the argument.'

語法 

Python中沒有強制的語句終止字元,且程式碼塊是透過縮排來指示的。縮排表示一個程式碼塊的開始,逆縮排則表示一個程式碼塊的結束。宣告以冒號(:)字元結束,並且開啟一個縮排級別。單行註釋以井號字元(#)開頭,多行註釋則以多行字串的形式出現。賦值(事實上是將物件繫結到名字)透過等號(“=”)實現,雙等號(“==”)用於相等判斷,”+=”和”-=”用於增加/減少運算(由符號右邊的值確定增加/減少的值)。這適用於許多資料型別,包括字串。你也可以在一行上使用多個變數。例如:

>>> myvar = 3
>>> myvar += 2
>>> myvar
5
>>> myvar -= 1
>>> myvar
4
"""This is a multiline comment.
The following lines concatenate the two strings."""
>>> mystring = "Hello"
>>> mystring += " world."
>>> print mystring
Hello world.
# This swaps the variables in one line(!).
# It doesn't violate strong typing because values aren't
# actually being assigned, but new objects are bound to
# the old names.
>>> myvar, mystring = mystring, myvar

資料型別 

Python具有列表(list)、元組(tuple)和字典(dictionaries)三種基本的資料結構,而集合(sets)則包含在集合庫中(但從Python2.5版本開始正式成為Python內建型別)。列表的特點跟一維陣列類似(當然你也可以建立類似多維陣列的“列表的列表”),字典則是具有關聯關係的陣列(通常也叫做雜湊表),而元組則是不可變的一維陣列(Python中“陣列”可以包含任何型別的元素,這樣你就可以使用混合元素,例如整數、字串或是巢狀包含列表、字典或元組)。陣列中第一個元素索引值(下標)為0,使用負數索引值能夠從後向前訪問陣列元素,-1表示最後一個元素。陣列元素還能指向函式。來看下面的用法:

>>> sample = [1, ["another", "list"], ("a", "tuple")]
>>> mylist = ["List item 1", 2, 3.14]
>>> mylist[0] = "List item 1 again" # We're changing the item.
>>> mylist[-1] = 3.21 # Here, we refer to the last item.
>>> mydict = {"Key 1": "Value 1", 2: 3, "pi": 3.14}
>>> mydict["pi"] = 3.15 # This is how you change dictionary values.
>>> mytuple = (1, 2, 3)
>>> myfunction = len
>>> print myfunction(mylist)
3

你可以使用:運算子訪問陣列中的某一段,如果:左邊為空則表示從第一個元素開始,同理:右邊為空則表示到最後一個元素結束。負數索引則表示從後向前數的位置(-1是最後一個專案),例如:

>>> mylist = ["List item 1", 2, 3.14]
>>> print mylist[:]
['List item 1', 2, 3.1400000000000001]
>>> print mylist[0:2]
['List item 1', 2]
>>> print mylist[-3:-1]
['List item 1', 2]
>>> print mylist[1:]
[2, 3.14]
# Adding a third parameter, "step" will have Python step in
# N item increments, rather than 1.
# E.g., this will return the first item, then go to the third and
# return that (so, items 0 and 2 in 0-indexing).
>>> print mylist[::2]
['List item 1', 3.14]

字串

Python中的字串使用單引號(‘)或是雙引號(“)來進行標示,並且你還能夠在透過某一種標示的字串中使用另外一種標示符(例如 “He said ‘hello’.”)。而多行字串可以透過三個連續的單引號(”’)或是雙引號(“”")來進行標示。Python可以透過u”This is a unicode string”這樣的語法使用Unicode字串。如果想透過變數來填充字串,那麼可以使用取模運算子(%)和一個元組。使用方式是在目標字串中從左至右使用%s來指代變數的位置,或者使用字典來代替,示例如下:

>>>print "Name: %s\
Number: %s\
String: %s" % (myclass.name, 3, 3 * "-")
Name: Poromenos
Number: 3
String: ---

strString = """This is
a multiline
string."""

# WARNING: Watch out for the trailing s in "%(key)s".
>>> print "This %(verb)s a %(noun)s." % {"noun": "test", "verb": "is"}
This is a test.

流程控制

Python中可以使用ifforwhile來實現流程控制。Python中並沒有select,取而代之使用if來實現。使用for來列舉列表中的元素。如果希望生成一個由數字組成的列表,則可以使用range(<number>)函式。以下是這些宣告的語法示例:

rangelist = range(10)
>>> print rangelist
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for number in rangelist:
    # Check if number is one of
    # the numbers in the tuple.
    if number in (3, 4, 7, 9):
        # "Break" terminates a for without
        # executing the "else" clause.
        break
    else:
        # "Continue" starts the next iteration
        # of the loop. It's rather useless here,
        # as it's the last statement of the loop.
        continue
else:
    # The "else" clause is optional and is
    # executed only if the loop didn't "break".
    pass # Do nothing

if rangelist[1] == 2:
    print "The second item (lists are 0-based) is 2"
elif rangelist[1] == 3:
    print "The second item (lists are 0-based) is 3"
else:
    print "Dunno"

while rangelist[1] == 1:
    pass

函式

函式透過“def”關鍵字進行宣告。可選引數以集合的方式出現在函式宣告中並緊跟著必選引數,可選引數可以在函式宣告中被賦予一個預設值。已命名的引數需要賦值。函式可以返回一個元組(使用元組拆包可以有效返回多個值)。Lambda函式是由一個單獨的語句組成的特殊函式,引數透過引用進行傳遞,但對於不可變型別(例如元組,整數,字串等)則不能夠被改變。這是因為只傳遞了該變數的記憶體地址,並且只有丟棄了舊的物件後,變數才能繫結一個物件,所以不可變型別是被替換而不是改變(譯者注:雖然Python傳遞的引數形式本質上是引用傳遞,但是會產生值傳遞的效果)。例如:

# Same as def funcvar(x): return x + 1
funcvar = lambda x: x + 1
>>> print funcvar(1)
2

# an_int and a_string are optional, they have default values
# if one is not passed (2 and "A default string", respectively).
def passing_example(a_list, an_int=2, a_string="A default string"):
    a_list.append("A new item")
    an_int = 4
    return a_list, an_int, a_string

>>> my_list = [1, 2, 3]
>>> my_int = 10
>>> print passing_example(my_list, my_int)
([1, 2, 3, 'A new item'], 4, "A default string")
>>> my_list
[1, 2, 3, 'A new item']
>>> my_int
10

Python支援有限的多繼承形式。私有變數和方法可以透過新增至少兩個前導下劃線和最多尾隨一個下劃線的形式進行宣告(如“__spam”,這只是慣例,而不是Python的強制要求)。當然,我們也可以給類的例項取任意名稱。例如:

class MyClass(object):
    common = 10
    def __init__(self):
        self.myvariable = 3
    def myfunction(self, arg1, arg2):
        return self.myvariable

    # This is the class instantiation
>>> classinstance = MyClass()
>>> classinstance.myfunction(1, 2)
3
# This variable is shared by all classes.
>>> classinstance2 = MyClass()
>>> classinstance.common
10
>>> classinstance2.common
10
# Note how we use the class name
# instead of the instance.
>>> MyClass.common = 30
>>> classinstance.common
30
>>> classinstance2.common
30
# This will not update the variable on the class,
# instead it will bind a new object to the old
# variable name.
>>> classinstance.common = 10
>>> classinstance.common
10
>>> classinstance2.common
30
>>> MyClass.common = 50
# This has not changed, because "common" is
# now an instance variable.
>>> classinstance.common
10
>>> classinstance2.common
50

# This class inherits from MyClass. The example
# class above inherits from "object", which makes
# it what's called a "new-style class".
# Multiple inheritance is declared as:
# class OtherClass(MyClass1, MyClass2, MyClassN)
class OtherClass(MyClass):
    # The "self" argument is passed automatically
    # and refers to the class instance, so you can set
    # instance variables as above, but from inside the class.
    def __init__(self, arg1):
        self.myvariable = 3
        print arg1

>>> classinstance = OtherClass("hello")
hello
>>> classinstance.myfunction(1, 2)
3
# This class doesn't have a .test member, but
# we can add one to the instance anyway. Note
# that this will only be a member of classinstance.
>>> classinstance.test = 10
>>> classinstance.test
10

異常

Python中的異常由 try-except [exceptionname] 塊處理,例如:

def some_function():
    try:
        # Division by zero raises an exception
        10 / 0
    except ZeroDivisionError:
        print "Oops, invalid."
    else:
        # Exception didn't occur, we're good.
        pass
    finally:
        # This is executed after the code block is run
        # and all exceptions have been handled, even
        # if a new exception is raised while handling.
        print "We're done with that."

>>> some_function()
Oops, invalid.
We're done with that.

匯入

外部庫可以使用 import [libname] 關鍵字來匯入。同時,你還可以用 from [libname] import [funcname] 來匯入所需要的函式。例如:

import random
from time import clock

randomint = random.randint(1, 100)
>>> print randomint
64

檔案I / O

Python針對檔案的處理有很多內建的函式庫可以呼叫。例如,這裡演示瞭如何序列化檔案(使用pickle庫將資料結構轉換為字串):

import pickle
mylist = ["This", "is", 4, 13327]
# Open the file C:\\binary.dat for writing. The letter r before the
# filename string is used to prevent backslash escaping.
myfile = open(r"C:\\binary.dat", "w")
pickle.dump(mylist, myfile)
myfile.close()

myfile = open(r"C:\\text.txt", "w")
myfile.write("This is a sample string")
myfile.close()

myfile = open(r"C:\\text.txt")
>>> print myfile.read()
'This is a sample string'
myfile.close()

# Open the file for reading.
myfile = open(r"C:\\binary.dat")
loadedlist = pickle.load(myfile)
myfile.close()
>>> print loadedlist
['This', 'is', 4, 13327]

其它雜項

  • 數值判斷可以連結使用,例如 1<a<3 能夠判斷變數 a 是否在1和3之間。
  • 可以使用 del 刪除變數或刪除陣列中的元素。
  • 列表推導式(List Comprehension)提供了一個建立和操作列表的有力工具。列表推導式由一個表示式以及緊跟著這個表示式的for語句構成,for語句還可以跟0個或多個if或for語句,來看下面的例子:
    >>> lst1 = [1, 2, 3]
    >>> lst2 = [3, 4, 5]
    >>> print [x * y for x in lst1 for y in lst2]
    [3, 4, 5, 6, 8, 10, 9, 12, 15]
    >>> print [x for x in lst1 if 4 > x > 1]
    [2, 3]
    # Check if a condition is true for any items.
    # "any" returns true if any item in the list is true.
    >>> any([i % 3 for i in [3, 3, 4, 4, 3]])
    True
    # This is because 4 % 3 = 1, and 1 is true, so any()
    # returns True.
    
    # Check for how many items a condition is true.
    >>> sum(1 for i in [3, 3, 4, 4, 3] if i == 4)
    2
    >>> del lst1[0]
    >>> print lst1
    [2, 3]
    >>> del lst1
  • 全域性變數在函式之外宣告,並且可以不需要任何特殊的宣告即能讀取,但如果你想要修改全域性變數的值,就必須在函式開始之處用global關鍵字進行宣告,否則Python會將此變數按照新的區域性變數處理(請注意,如果不注意很容易被坑)。例如:
    number = 5
    
    def myfunc():
        # This will print 5.
        print number
    
    def anotherfunc():
        # This raises an exception because the variable has not
        # been bound before printing. Python knows that it an
        # object will be bound to it later and creates a new, local
        # object instead of accessing the global one.
        print number
        number = 3
    
    def yetanotherfunc():
        global number
        # This will correctly change the global.
        number = 3

小結

本教程並未涵蓋Python語言的全部內容(甚至連一小部分都稱不上)。Python有非常多的庫以及很多的功能特點需要學習,所以要想學好Python你必須在此教程之外透過其它方式,例如閱讀Dive into Python。我希望這個教程能給你一個很好的入門指導。如果你覺得本文還有什麼地方值得改進或新增,或是你希望能夠了解Python的哪方面內容,請留言。

本教程適合作一個簡短的電子書。電子書後續額外提供的各種Python最佳實踐都在一本獨立的電子書裡,感興趣的同學可以到 https://leanpub.com/learn-python 購買。購買後可以免費獲取更新。

相關文章