Python語法及語義Python語法及語義(Python syntax and semantics),Python編程語言之語法是一組Python的運作編程規則,用於定義Python程序如何來編寫與編譯(由運行時系統與程式師來操作)。Python語言與Perl、C,以及Java有許多相似之處,不過在這些語言之間仍存在著一些明確的差異[1]。 設計理念Python被設計為一種高度可讀的程式語言。[1]它具有相對排列有致的視覺佈局,並且在其他編程語言使用標點符號的情況下經常使用英文關鍵字。Python的目標是在其語法設計中保持簡單與一致性,在「Python之禪」一書中的「宣示」也提到「應該有一種——最好只有一種——明顯的方法來達成Python簡單與一致性的目標」。[1] 如上述、Python的「宣示」即「應該有一種——最好只有一種——明顯的方法來達成Python簡單與一致性的目標」;而這個宣示故意跟「Perl」及「Ruby」的宣示「不止只有一種方法可以達成目標」唱反調。 關鍵字Python有35個關鍵字或保留字;這些關鍵字或保留字不能用作標識符。[2][3]
首行縮排Python 使用空白字元來分隔控制流程區塊(遵循越位規則)。 Python 借鑒了其前身ABC 的這一特性:它使用首行縮排來表示代碼塊的運作,而不是標點符號或關鍵字。 在所謂的"自由格式"(free-format)的程式語言中——使用源自ALGOL的區塊結構——代碼區塊會使用大括號( 一個名為 def foo(x):
if x == 0:
bar()
else:
baz(x)
foo(x - 1)
void foo(int x)
{
if (x == 0) {
bar();
} else {
baz(x);
foo(x - 1);
}
}
不正確的縮排代碼可能會被人誤讀,而不是被編譯器或直譯器解譯。 比如,如果上例中最後一行的函數呼叫 def foo(x):
if x == 0:
bar()
else:
baz(x)
foo(x - 1)
造成上例編程無論如何最後一行都會被執行,即使 雖然空格和製表鍵都被接受作為縮排的形式,並且可以使用任意倍數的空格,也建議使用空格作為不同的架構區分[5];並且在標準上建議區分不同的巢狀結構使用 4 個空格的形式(如上例所示),這也是迄今為止最常用的空格佈局形態。[6][7]從 Python 3[8]開始,不允許在同一源代碼文件中的連續行上混合空格和製表符,這會導致產生難以發現的錯誤;因為有許多工具無法在視覺上區分空格與製表鍵。 資料結構由於 Python 是一種動態類型的程式語言,因此 Python 值不是一種變量攜帶資料類型信息。 Python 中的所有變量都持有對對象的參照,這些參照被傳遞給函數; 函數不能在其呼叫函數中更改變量參照的值(但請參閱下面的例外情況)。有些人(包括吉多·範羅蘇姆本人)將這種參數傳遞方案稱為"依物件參照呼叫"。"對象參照"意味著一個名稱,"傳遞參照"是一個"別名",即是對同一物件的參照副本,就像在 C/C++ 中一樣。物件的值可以在被呼叫的函數中用“別名”改變,比如: >>> alist = ['a', 'b', 'c']
>>> def my_func(al):
... al.append('x')
... print(al)
...
>>> my_func(alist)
['a', 'b', 'c', 'x']
>>> alist
['a', 'b', 'c', 'x']
函數 在動態類型語言中,Python 進行了適度的類型檢查。 隱式轉換是為數字類型(以及布爾值)定義的,因此可以有效地將複數乘以整數(例如)而沒有顯式轉換。 但是,例如數字和字符串之間沒有隱式轉換; 字符串是需要數字之數學函數的無效參數。 基本類型Python 具有廣泛的基本數據類型。 除了傳統的整數以及浮點數算術外,它透明地支持高精度計算、複數,及十進制數。 集合類型Python非常有用的方面之的是集合(或容器)類型的概念。 一般來說,集合是一個以易於引用、或則索引的方式包含其他對象的物件。 集合有兩種基本形式:序列與映射。 物件系統在Python中,一切都是物件,甚至是類屬。類屬,作為物件,有一個類屬,稱為它們的元類。Python亦支持多重繼承以及Mixin。 Python語言支持對類型以及類屬的廣泛自檢。 可以讀取與比較類型——而所謂的類型是指類型的實例。 物件的屬性可以提取為字典。 文字字符串Python有各種字符串文字。 普通字符串文字單引號或雙引號均可用於引用字符串。 與Unix shell語言、Perl,或受Perl影響的語言(諸如Ruby 或Groovy)不同,單引號和雙引號的功能相同,即$foo表達式沒有字符串插值。然而,可以通過多種方式進行插值:使用“f-strings”(自Python 3.6[9]開始)、使用格式方法或者舊的%字符串格式的運算符。 比如,所有這些 Python 的宣告語句: print(f"I just printed {num} pages to the printer {printer}")
print("I just printed {} pages to the printer {}".format(num, printer))
print("I just printed {0} pages to the printer {1}".format(num, printer))
print("I just printed {num} pages to the printer {printer}".format(num=num, printer=printer))
print("I just printed %s pages to the printer %s" % (num, printer))
print("I just printed %(num)s pages to the printer %(printer)s" % {"num": num, "printer": printer})
等價於Perl的宣告語句: print "I just printed $num pages to the printer $printer\n"
語句使用變量 多行字符串文字還有多行字符串,它們以一系列三個單引號或雙引號開頭及結尾,而其功能類似於Perl與Ruby中的Here文档。 字符串內插值的一個簡單示例(使用格式的方法)比如: print("""Dear {recipient},
I wish you to leave Sunnydale and never return.
Not Quite Love,
{sender}
""".format(sender="Buffy the Vampire Slayer", recipient="Spike"))
原始字符串範例包括: >>> # A Windows path, even raw strings cannot end in a backslash
>>> r"C:\Foo\Bar\Baz\"
File "<stdin>", line 1
r"C:\Foo\Bar\Baz\"
^
SyntaxError: EOL while scanning string literal
>>> dos_path = r"C:\Foo\Bar\Baz\ " # avoids the error by adding
>>> dos_path.rstrip() # and removing trailing space
'C:\\Foo\\Bar\\Baz\\'
>>> quoted_dos_path = r'"{}"'.format(dos_path)
>>> quoted_dos_path
'"C:\\Foo\\Bar\\Baz\\ "'
>>> # A regular expression matching a quoted string with possible backslash quoting
>>> re.match(r'"(([^"\\]|\\.)*)"', quoted_dos_path).group(1).rstrip()
'C:\\Foo\\Bar\\Baz\\'
>>> code = 'foo(2, bar)'
>>> # Reverse the arguments in a two-arg function call
>>> re.sub(r'\(([^,]*?),([^ ,]*?)\)', r'(\2, \1)', code)
'foo(2, bar)'
>>> # Note that this won't work if either argument has parens or commas in it.
相鄰字符串文字的串聯因此 title = "One Good Turn: " \
'A Natural History of the Screwdriver and the Screw'
相當於 title = "One Good Turn: A Natural History of the Screwdriver and the Screw"
Unicode從Python 3.0開始,源代碼與直譯器的默認字符集都是UTF-8。在UTF-8中,Unicode字符串的處理方式及傳統的字節字符串類似。這個例子將起如下作用: s = "Γειά" # Hello in Greek
print(s)
數字Python中的數字文字是屬於普通類型,例如: 列表、多元组、集合、字典Python具有支持創建容器類型的語法。 列表(類屬列表)是任意類型項目的可變序列,可以使用特殊語法來創建。 a_list = [1, 2, 3, "a dog"]
或使用普通物件來創建 a_second_list = list()
a_second_list.append(4)
a_second_list.append(5)
多元組(類屬元組)是任意類型項目的不可變序列。還有一個特殊的語法來創建多元組 a_tuple = 1, 2, 3, "four"
a_tuple = (1, 2, 3, "four")
運算符算術在算術上Python包括 >>> 4 / 2
2.0
接著 在Python 2(及大多數其他編程語言)中,除非明確要求,否則 比較運算符比較運算符(comparison operator),比如: 諸如 對於沒有副作用的表達式, 邏輯運算符在所有版本的Python裏面,布爾運算符處理零值或空值、諸如 布爾運算符(boolean operator) 函數式編程如上所述,Python的另一個優勢是函數式編程風格的可用性。正如所料,這使得使用列表及其他集合更加簡單。 理解L = [mapping_expression for element in source_list if filter_expression]
第一級函數在Python中,函數是可以動態創建以及傳遞的第一級物件。 Python對匿名函數的有限支持是 f = lambda x: x**2
f(5)
Lambda僅限於包含表達式而不是語句陳述式,儘管"控制流"(control flow)仍可以通過使用短路在lambda中不太優雅地實現編程,[11]並且更習慣地使用"條件表達式"(conditional expression)。[12] 閉包def derivative(f, dx):
"""Return a function that approximates the derivative of f
using an interval of dx, which should be appropriately small.
"""
def function(x):
return (f(x + dx) - f(x)) / dx
return function
生成器from itertools import count
def generate_primes(stop_at=None):
primes = []
for n in count(start=2):
if stop_at is not None and n > stop_at:
return # raises the StopIteration exception
composite = False
for p in primes:
if not n % p:
composite = True
break
elif p ** 2 > n:
break
if not composite:
primes.append(n)
yield n
生成器表達式在Python 2.4中引入的生成器表達式是列表推導式的惰性求值等價式。使用上一節中提供的質數生成器,我們可以定義一個惰性求值方式但不是無限的集合。 from itertools import islice
primes_under_million = (i for i in generate_primes() if i < 1000000)
two_thousandth_prime = islice(primes_under_million, 1999, 2000).next()
primes_under_million = [i for i in generate_primes(2000000) if i < 1000000]
two_thousandth_prime = primes_under_million[1999]
字典與集合推導式>>> dict((n, n*n) for n in range(5))
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
Python 2.7及3.0通過引入字典與集合推導式來統一所有集合類型,類似於列表推導式: >>> [n*n for n in range(5)] # regular list comprehension
[0, 1, 4, 9, 16]
>>>
>>> {n*n for n in range(5)} # set comprehension
{0, 1, 4, 9, 16}
>>>
>>> {n: n*n for n in range(5)} # dict comprehension
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
物件Python支持大多數面向物件編程(OOP)技術。 With 宣告關於 屬性屬性允許使用及屬性揭取相同的語法在物件實例上調用專門定義的方法。 定義一些屬性的類屬的一個例子是: class MyClass:
def __init__(self):
self._a = None
@property
def a(self):
return self._a
@a.setter # makes the property writable
def a(self, value):
self._a = value
描述符定義三個特殊方法 類屬與靜態法Python允許通過使用@cla 異常在第一個代碼的示例中,遵循LBYL的方法,在揭取之前對屬性進行了外顯的檢查: if hasattr(spam, 'eggs'):
ham = spam.eggs
else:
handle_missing_attr()
第二個示例遵循EAFP範式: try:
ham = spam.eggs
except AttributeError:
handle_missing_attr()
説明與文檔字符串説明一段代碼: import sys
def getline():
return sys.stdin.readline() # Get one line and return it
用多行説明一段代碼: def getline():
return sys.stdin.readline() """this function
gets one line
and returns it"""
函數註解函數註解(類型提示)在PEP3107中定義。[15]函數註解允許將數據附加到函數的參數以及返回原址。註釋的特性不是由程式語言所定義的,而是留給第三方框架的來進行的。例如,可以編寫一個數據庫來處理靜態類型的程式語言架構:[15] def haul(item: Haulable, *vargs: PackAnimal) -> Distance
修飾子修飾子(裝飾器;修飾符)是用於修改函數、方法,或則類定義的任何可調用的 Python 物件。修飾子傳遞正被定義的原始物件、並返回修改後的物件;然後將其綁定到定義中的名稱之上。Python 修飾子部分受到 Java 註釋運用的啟發,並且具有類似 Java 的語法;修飾子語法是純粹的語法糖,使用 @ 作為修飾子的關鍵字: @viking_chorus
def menu_item():
print("spam")
相當於 def menu_item():
print("spam")
menu_item = viking_chorus(menu_item)
修飾子是元編程的一種形式; 它們增強了它們修飾的函數或方法的作用。 比如,在下面的示例中,viking_chorus 可能會導致 menu_item 每次被呼叫時運行 8 次(參見小品喜劇(Spam)): def viking_chorus(myfunc):
def inner_func(*args, **kwargs):
for i in range(8):
myfunc(*args, **kwargs)
return inner_func
函數修飾子的典型用途是創建類方法或靜態方法、添加函數屬性、追踪、設置前置及後置條件以及同步,[16]不過可以用於更多方面,包括尾遞歸、[17]記憶化;甚至改進其他修飾子的編寫。[18] 修飾子的作用;即是可以經由在主要程式語言相鄰且相關的行之上置放幾個修飾子、進而來帶動主程式鏈接修飾子之間的連繫: @invincible
@favourite_colour("Blue")
def black_knight():
pass
相當於 def black_knight():
pass
black_knight = invincible(favourite_colour("Blue")(black_knight))
或者,使用中介架構的變數、如下程式所示: def black_knight():
pass
blue_decorator = favourite_colour("Blue")
decorated_by_blue = blue_decorator(black_knight)
black_knight = invincible(decorated_by_blue)
在上述的例子中,favourite_colour 修飾子工廠接受一個參數。 修飾子工廠必須返回一個修飾子,然後使用要修飾的物件作為參數來呼叫它: def favourite_colour(colour):
def decorator(func):
def wrapper():
print(colour)
func()
return wrapper
return decorator
復活節彩蛋一個隱藏信息,Python之禪(Python設計哲學的總結),在嘗試 註釋
參閱
外部連接
|
Portal di Ensiklopedia Dunia