第一篇 Python語言基礎
第2章 Python必須知道的基礎語法
2.1 Python的檔案類型
import py_compile
py_compile.compile('hello.py')
cd /D
D:\developer\python\example\02\2.1
python -O –m py_compile
hello.py
2.2 Python的編碼規範
01 # 變數、模組名的命名規則
02
# Filename: ruleModule.py
03
04
_rule = "rule information"
01
class Student:
# 類名大寫
02
__name = "" # 私有執行個體變數前必須有兩個底線
03 def __init__(self, name):
04 self.__name = name # self相當於Java中的this
05 def getName(self): # 方法名首字母小寫,其後每個單詞的首字母大寫
06 return self.__name
07
08
if __name__ == "__main__":
09 student =
Student("borphi") # 對象名小寫
10 print(student.getName())
randrange(start, stop[,
step])
randrange(1, 9, 2)
01
# 函數中的命名規則
02
import random
03
04
def compareNum(num1, num2):
05 if(num1 > num2):
06 return 1
07 elif(num1 == num2):
08 return 0
09 else:
10 return -1
11
num1 = random.randrange(1, 9)
12
num2 = random.randrange(1, 9)
13
print( "num1 =", num1)
14
print ("num2 =", num2)
15
print (compareNum(num1, num2))
01 # 不规范的变量命名
02 sum = 0
03 i = 2000
04 j = 1200
05 sum = i + 12 * j
這段代碼定義了一個求和變數sum,以及兩個變數i、j。如果只看代碼片段,並不知道運算的含義是什麼,需要通讀整個函數或功能模組才能理解此處運算式的含義。
01 # 规范的变量命名
02 sumPay = 0
03 bonusOfYear = 2000
04 monthPay = 1200
05 sumPay = bonusOfYear + 12 * monthPay
01
x = 1
02
if x == 1:
03 print( "x =", x) # 代碼縮進
04
else:
05 print( "x =", x) # 代碼縮進
06 x = x + 1 # 代碼縮進
07
print ("x =", x)
x = 1
x = 1
01 x = 0
02 if x == 1:
03 print( "x =", x)
04 else:
05 print( "x =", x) # 代码缩进
06 x = x + 1 # 代码缩进
07 print ("x =", x)
IndentationError: expected
an indented block
01
x = 1
02
if x == 1:
03 print( "x =", x) # 代碼縮進
04
else:
05 print( "x =", x) # 代碼縮進
06
x = x + 1
07
print( "x =", x)
x = 2
01
# 規範導入方式
02
import sys
03
04
print (sys.path)
05
print (sys.argv)
['D:\\developer\\python\\example\\02\\2.2\\2.2.3','C:\\WINDOWS\\system32\\python25.zip',
'D:\\developer\\python\\DLLs',
'D:\\developer\\python\\lib',
'D:\\developer\\python\\lib\\plat-win',
'D:\\developer\\python\\lib\\lib-tk','D:\\developer\\python',
'D:\\developer\\python\\lib\\site-packages','D:\\developer\\python\\lib\\site-packages\\win32',
'D:\\developer\\python\\lib\\site-packages\\win32\\lib',
'D:\\developer\\python\\lib\\site-packages\\Pythonwin',
'D:\\developer\\python\\lib\\site-packages\\wx-2.8-msw-unicode']
['import.py']
01
#不規範導入方式
02
from sys import path
03
from sys import argv
04
05
print (path)
06
print (argv)
2.2.4 使用空行分隔代碼
函數之間或類的方法之間用空行分隔,表示一段新的代碼的開始。類和函數入口之間也用一行空行分隔,突出函數入口的開始。下面這段代碼創建了一個類A,類A中定義了兩個方法funX()和funY()。
01
class A:
02 def funX(self):
03 print( "funY()")
04
05 def funY(self):
06 print ("funY()")
07
08
if __name__ == "__main__":
09 a = A()
10 a.funX()
11 a.funY()
【代碼說明】
·第4行代碼插入了一個空行,便於程式師閱讀代碼,表示區分方法之間的間隔。
·第7行代碼也是一個空行。因為下面的if語句是主程序的入口,用於創建類A的物件,並調用其方法。
空行與代碼縮進不同,空行並不是Python語法的一部分。書寫時不插入空行,Python解譯器運行也不會出錯。但是空行的作用在於分隔了兩段不同功能或含義的代碼,便於日後代碼的維護或重構。記住,空行也是程式碼的一部分。
2.2.5 正確的注釋
注釋是用於說明代碼實現的功能、採用的演算法、代碼的編寫者以及代碼創建和修改的時間等資訊。注釋是代碼的一部分,注釋起到了對代碼補充說明的作用。C、C++、Java均採用“//”或“/**/”作為注釋的標記,Python的注釋方式有所不同。如果只對一行代碼注釋,使用“#”加若干空格開始,後面是注釋的內容。如果對一段代碼進行注釋,也使用“#”,段落之間以一個“#”行分隔。Python會忽略“#”行的內容,跳過“#”行執行後面的內容。下面的代碼演示了Python的注釋。
01
# note - show Python's note
02
# Copyright (C) 2008 bigmarten
03
#
04
# This program is free software. you can redistribute it and/or modify
05
# it under the terms of the GNU General Public License as published by
06
# the Free Software Foundation
07 #
08
########################################################################
09
#
10
# Version is 1.0
11
#
12
# Its contents are calculate payment
13
#
14
########################################################################
15
16
# 規範的變數命名
17
sumPay = 0 # 年薪
18
bonusOfYear = 2000 # 年終獎金
19
monthPay = 1200
# 月薪
20
sumPay = bonusOfYear + 12 * monthPay # 年薪 = 年終獎金 + 12 * 月薪
【代碼說明】
·第1行代碼對本檔進行摘要說明。
·第2行代碼聲明了版權資訊。
·第3行代碼是空行,說明下面將另起一段,注釋其他的內容。
·第4行到第6行代碼說明程式的許可資訊。
·第8行到第14行代碼說明程式的版本和實現的功能。
·第16行開始的代碼實現程式的功能,並在行末對每行代碼進行單行注釋。
Python還有一些特殊的注釋,完成一些特別的功能,如中文注釋、程式的跨平臺。
(1)中文注釋:如果需要在代碼中使用中文注釋,必須在Python檔的最前面加上如下注釋說明。
# -*- coding: UTF-8 -*-
注意 Python3中預設的編碼是Unicode,所以不需在每個Python檔中再加以上注釋,但在Python2中若使用中文則必須加上。
(2)跨平臺注釋:如果需要使Python程式運行在*nix系統中,最好在Python檔的最前面加上如下注釋說明。
#!/usr/bin/python
此外,注釋也用於偵錯工具。由於文字編輯器不具備調試功能,因此,可以使用注釋輔助調試。如果一個程式很長,可以把程式分成若干個部分編寫。為了更好地調試目前正在編寫的程式模組,可以將那些已經編譯通過的部分注釋掉;或者把多餘代碼注釋掉,把主要精力集中在當前編寫的邏輯上。
例如,編寫一個比較兩個數位大小的函數。
01
def compareNum(num1, num2):
02 if(num1 > num2):
03 return str(num1)+" >
"+str(num2)
04 elif(num1 < num2):
05 return str(num1)+" =
"+str(num2)
06 elif(num1 == num2):
07 return str(num1)+" =
"+str(num2)
08 else:
09 return ""
【代碼說明】 本段代碼中的str()函數實現了數位類型到字串類型的轉換。
編譯後顯示如下內容:
---------- python ----------
輸出完成 (耗時: 1 秒) - 正常終止
說明這個函數編譯通過,至少在語法上沒有任何錯誤。下面就可以編寫這個函數的調用程式,證明這個程式的邏輯是否正確。在前面的程式碼片段後面添加如下代碼。
01
num1 = 2
02
num2 = 1
03
print (compareNum(num1, num2))
04
num1 = 2
05
num2 = 2
06
print (compareNum(num1, num2))
07
num1 = 1
08
num2 = 2
09
print (compareNum(num1, num2))
運行程式,發現第3行的輸出結果有誤。
2 > 1
2 = 2
1 = 2
第1行和第2行的輸出證明函數compareNum()中num1>num2和num1==num2的判斷是正確的,於是想到程式可能是在num1<num2的條件判斷的邏輯上出現了錯誤。為了證明這個觀點,注釋掉num1<num2的分支判斷語句。注釋後的compareNum()的代碼如下。
01
def compareNum(num1, num2):
02 if(num1 > num2):
03 return str(num1)+" >
"+str(num2)
04 #elif(num1 < num2):
05
# return str(num1)+" = "+str(num2)
06 elif(num1 == num2):
07 return str(num1)+" =
"+str(num2)
08 else:
09 return ""
此時,程式編譯通過,證明邏輯錯誤就在num1<num2的分支語句中。仔細檢查注釋的語句,發現return語句的返回值運算式寫錯了,其中的“>”誤寫為“=”。compareNum()正確的寫法如下所示。
01
def compareNum(num1, num2):
02 if(num1 > num2):
03 return str(num1)+" >
"+str(num2)
04 elif(num1 < num2):
05 return str(num1)+" <
"+str(num2)
06 elif(num1 == num2):
07 return str(num1)+" =
"+str(num2)
08 else:
09 return ""
再次運行整個程式,輸出結果正確顯示。
2 > 1
2 = 2
1 < 2
合理地使用注釋可以檢查程式中的錯誤。這段代碼演示了注釋問題語句的做法,並檢查這些語句錯誤的過程。另一種用法是,注釋正確語句,單獨運行問題語句,檢查語句錯誤。這兩種用法可以根據實際情況分別應用,後者更適合於代碼比較長的情況。注釋對於程式非常重要,表2-1說明了注釋的用法和作用。
表2-1 注釋的用法
2.2.6 語句的分隔
分號是C、Java等語言中標識語句結束的標誌。Python也支持分號,同樣可以用分號作為一行語句的結束標識。但在Python中分號的作用已經不像在C、Java中那麼重要了,在C、Java中分號是必需的;而Python中的分號可以省略,主要通過換行來識別語句的結束。例如,以下兩行代碼是等價的。
01
# 下麵兩條語句是等價的
02
print( "hello world!")
03
print( "hello world!");
【代碼說明】
·第1行代碼的輸出結果:
hello world!
·第2行代碼的輸出結果:
hello world!
如果要在一行中書寫多個語句,就必須使用分號分隔了,否則Python無法識別語句之間的間隔。
01
# 使用分號分隔語句
02
x = 1; y = 1 ; z = 1
【代碼說明】 第2行代碼中有3條設定陳述式,語句之間需要用分號隔開。如果不隔開語句,則Python解譯器不能正確解釋,會提示語法錯誤。
SyntaxError: invalid syntax
注意 分號並不是Python推薦使用的符號,Python傾向於使用換行作為每條語句的分隔。簡單直白是Python語法的特點,通常一行只寫一條語句,這樣便於閱讀和理解程式。一行寫多條語句的方式是不好的實踐。
Python同樣支持多行寫一條語句,Python使用“\”作為分行符號。在實踐中,一條語句寫在多行也是很常見的。例如,把SQL語句作為參數傳遞給函數,由於SQL非常長,因此需要換行書寫,提高閱讀的方便性。
01
# 字串的換行
02
# 寫法一
03
sql = "select id,name \
04
from dept \
05
where name = 'A'"
06
print (sql)
07
# 寫法二
08
sql = "select id,name " \
09
"from dept " \
10 "where name = 'A'"
11
print (sql)
【代碼說明】
·寫法一隻使用了一對雙引號,把SQL語句分為select、from、where 3部分分別書寫。
·第6行代碼輸出結果如下。
select id,name from dept where name =
'A'
·寫法二使用了3對雙引號,select、from、where分別對應一對雙引號。
·第11行代碼輸出結果如下。
select id,name from dept where name =
'A'
第二種寫法比第一種寫法的可讀性更強,可以使用空格和定位字元對齊語句,使代碼顯得更工整。對於簡短的語句不推薦使用換行的寫法,這種寫法只會造成閱讀的複雜性。下面這段程式是不合理的換行寫法。
01
# 一條語句寫在多行
02
print (\
03
"hello world!")
【代碼說明】 第2、3行代碼是一個整體,調用print輸出“hello
world!”,這種情況不適合分行書寫。
2.3 變數和常量
變數是電腦記憶體中的一塊區域,變數可以存儲任何值,而且值可以改變。常量是一塊唯讀的記憶體區域,常量一旦初始化就不能修改。
2.3.1 變數的命名
變數由字母、數位或底線組成。變數的第1個字元必須是字母或底線,其他字元可以由字母、數位或底線組成。例如:
01
# 正確的變數命名
02
var_1 = 1
03
print (var_1)
04
_var1 = 2
05
print( _var1)
【代碼說明】
·第2行代碼定義了一個名為var_1的變數,該變數的初始值為1。這個變數以字母開頭,後面的字元由字母、底線和數位組成。
·第3行代碼輸出結果如下。
1
·第4行代碼定義了一個名為_var1的變數,該變數的初始值為2。這個變數以底線開頭,後面的字元由字母和數位組成。
·第5行代碼輸出結果如下。
2
下面這段代碼演示了錯誤的變數命名方式。
01
# 錯誤的變數命名
02
1_var = 3
03
print (1_var)
04
$var = 4
05
print ($var)
【代碼說明】
·第2行代碼定義了一個名為1_var的變數,該變數以數位開頭,後面的字元由字母、底線組成。
·第3行代碼,變數以數位開頭,不符合變數命名的規則。提示如下錯誤:
SyntaxError: invalid syntax
·第4行代碼定義了一個名為$var的變數,該變數以$符號開頭。
·第5行代碼,變數以$符號開頭,不符合變數命名的規則。提示如下錯誤:
SyntaxError: invalid syntax
2.3.2 變數的賦值
Python中的變數不需要聲明,變數的賦值操作即是變數聲明和定義的過程。每個變數在記憶體中創建,都包括變數的標識、名稱和資料這些資訊。例如:
x = 1
上面的代碼創建了一個變數x,並且賦值為1,如圖2-1所示。
01
# 一次新的賦值操作,將創建一個新的變數
02
x = 1
03
print (id(x))
04
x = 2
05
print( id(x))
【代碼說明】
·第2行代碼定義了一個名為x的變數,該變數的初始值為1。
·第3行代碼,輸出變數x的標識。輸出結果如下。
11229424
·第4行代碼再次定義了一個x的變數,該變數的初始值為2。該變數與前面的變數x並不是同一變數。
·第5行代碼,輸出變數x的標識。輸出結果如下。
11229412
如果變數沒有賦值,Python將認為該變數不存在。例如:
print y
運行後,解譯器提示:
NameError: name 'y' is not defined
在變數y沒有賦值的前提下,不能直接輸出y的值。每個變數在使用前都必須賦值,這樣可以避免由於變數的空值引起的一些異常。Python支援對一些變數同時賦值的操作,例如:
01
# 給多個變數賦值
02
a = (1, 2, 3)
03
(x, y, z) = a
04
print( "x =", x)
05
print( "y =", y)
06
print( "z =", z)
【代碼說明】
·第2行代碼定義了一個序列a,這個序列有3個值:1、2、3。
·第3行代碼,把序列a的值分別賦值給序列(x,y,z)中的變數x、y、z。
·第4行代碼輸出變數x的值。輸出結果:
x = 1
·第5行代碼輸出變數y的值。輸出結果:
y = 2
·第6行代碼輸出變數z的值。輸出結果:
z = 3
通過序列的裝包和拆包操作,實現了同時給多個變數賦值。關於序列的概念參見第4章的內容。
2.3.3 區域變數
區域變數是只能在函數或程式碼片段內使用的變數。函數或程式碼片段一旦結束,區域變數的生命週期也就結束。區域變數的作用範圍只在其被創建的函數內有效。例如,檔1的fun()中定義了一個區域變數,則該區域變數只能被fun()訪問,而不能被fun2()訪問,也不能被檔2訪問,如圖2-2所示。
下面定義了一個函數fun(),該函數中定義了一個區域變數。
01
# 區域變數
02
def fun():
03 local = 1
04 print(local)
05
fun()
【代碼說明】
·第2行代碼定義了一個函數fun()。
·第3行代碼定義了一個區域變數local。
·第4行代碼輸出local的值。輸出結果如下。
1
·第5行代碼調用函數fun()。此時已超出local變數的作用範圍。
注意 Python創建的變數就是一個物件,Python會管理變數的生命週期。Python對變數的回收採用的是垃圾回收機制。
2.3.4 全域變數
全域變數是能夠被不同的函數、類或檔共用的變數,在函數之外定義的變數都可以稱為全域變數。全域變數可以被檔內部的任何函數和外部檔訪問。例如,如果檔1中定義了一個全域變數,檔1中的函數fun()可以訪問該全域變數。此外,該全域變數也能被檔1、檔2訪問,如圖2-3所示。
01
# 在檔的開頭定義全域變數
02
_a = 1
03
_b = 2
04
def add():
05
global _a
06 _a = 3
07 return "_a + _b =", _a + _b
08
def sub():
09 global _b
10 _b = 4
11 return "_a - _b =", _a - _b
12
print (add())
13
print( sub())
【代碼說明】
·第2行代碼定義了一個名為_a的全域變數,這個變數的作用範圍從定義處到檔的結尾。之所以使用底線是為了區分於其他變數,引起程式師對全域變數出現的重視。
·第3行代碼定義了一個名為_b的全域變數。同樣,變數_b的作用範圍從定義處到檔的結尾。
·第4行代碼定義了一個函數add(),用於執行加法計算。
·第5行代碼引用全域變數_a。這裡使用了global關鍵字,global用於引用全域變數。
·第6行代碼對全域變數_a重新賦值。
·第7行代碼返回_a+_b的值。
·第8行代碼定義了一個函數sub(),用於執行減法運算。函數內的實現方式和add()相同。
·第12代碼調用函數add()。輸出結果如下。
('_a + _b =', 5)
·第13行代碼調用函數sub()。輸出結果如下。
('_a - _b =', -1)
如果不使用global關鍵字引用全域變數,而直接對_a、_b賦值,將得到不正確的結果。
01
# 錯誤地使用全域變數
02
_a = 1
03
_b = 2
04
def add():
05 _a = 3
06 return "_a + _b =", _a + _b
07
def sub():
08 _b = 4
09 return "_a - _b =", _a - _b
10
print (add())
11
print (sub())
【代碼說明】
·第5行代碼中的_a並不是前面定義的全域變數,而是函數add()中的區域變數。雖然輸出的結果相同,但是運算的物件並不相同。
·第6行代碼中的_b還是前面定義的全域變數_b。
·第8行代碼中的_b是區域變數。
·第10行代碼的輸出結果如下。
('_a + _b =', 5)
·第11行代碼的輸出結果如下。
('_a - _b =', -3)
注意 變數名相同的兩個變數可能並不是同一個變數,變數的名稱只是起標識的作用。變數出現的位置不同,變數的含義也不同。
同樣可以把全域變數放到一個專門的檔中,便於統一管理和修改。創建一個名為gl.py的文件。
01
# 全域變數
02
_a = 1
03
_b = 2
【代碼說明】 pl.py創建了兩個全域變數_a和_b。
再創建一個調用全域變數的檔use_global.py。
01
# 調用全域變數
02
import gl
03
def fun():
04 print(gl._a)
05 print(gl._b)
06
fun()
【代碼說明】
·第2行代碼導入前面創建的檔gl.py,即模組gl。
·第3行代碼定義了一個函數fun(),該函式呼叫全域變數_a和_b。這裡不需要使用global引用gl.py中的全域變數,因為前置字元可以定位全域變數_a和_b。
·第4行代碼輸出_a的值,使用前置字元gl定位。輸出結果:
1
·第5行代碼輸出_b的值,使用前置字元gl定位。輸出結果:
2
·第6行代碼調用fun()。
應該儘量避免使用全域變數。因為不同的模組都可以自由地訪問全域變數,可能會導致全域變數的不可預知性。對於gl.py中的全域變數,如果程式師甲修改了_a的值,程式師乙同時也要使用_a,這時可能導致程式中的錯誤。這種錯誤是很難發現和更正的。
全域變數降低了函數或模組之間的通用性,不同的函數或模組都要依賴於全域變數。同樣,全域變數降低了代碼的可讀性,閱讀者可能並不知道調用的某個變數是全域變數。
2.3.5 常量
常量是指一旦初始化後就不能改變的變數。例如,數位5、字串“abc”都是常量。C++中使用const關鍵字指定常量,Java使用static和final關鍵字指定常量,而Python並沒有提供定義常量的關鍵字。Python是一門功能強大的語言,可以自己定義一個常量類來實現常量的功能。在《Python Cookbook》一書中定義了一個常量模組const。
01
class _const: # 定義常量類_const
02
class ConstError(TypeError): pass
# 繼承自TypeError
03
def __setattr__(self,name,value):
04 if self.__dict__.has_key(name): # 如果__dict__中不包含對應的key則拋出錯誤
05 raise self.ConstError,
"Can't rebind const(%s)"%name
06 self.__dict__[name]=value
07
import sys
08
sys.modules[__name__]=_const() # 將const註冊進sys.modules的全域dict中
【代碼說明】
·這個類定義了一個方法__setattr__()和一個異常類型ConstError,ConstError類繼承自TypeError。通過調用類自帶的字典__dict__,判斷定義的常量是否包含在字典中。如果字典中包含此常量,將拋出異常。否則,給新創建的常量賦值。
·最後兩行代碼的作用是把const類註冊到sys.modules這個全域字典中。
以下代碼在use_const.py中調用const,定義常量。
01
import const
02
const.magic = 23
03
const.magic = 33
【代碼說明】
·第1行代碼導入const模組。
·第2行代碼定義了一個常量magic。
·第3行代碼修改常量magic的值,拋出異常。
const.ConstError: Can't rebind
const(magic)
2.4 資料類型
資料類型是構成程式設計語言語法的基礎。不同的程式設計語言有不同的資料類型,但都具有常用的幾種資料類型。Python有幾種內置的資料類型——數位、字串、元組、清單和字典。本節將重點介紹數位和字串。
2.4.1 數字
Python3的數位類型分為整型、浮點型、布林型、分數類型、複數類型。使用Python編寫程式時,不需要聲明變數的類型。由Python內置的基底資料型別來管理變數,在程式的後臺實現數值與類型的關聯,以及類型轉換等操作。Python與其他高階語言定義變數的方式及內部原理有很大的不同。在C或Java中,定義一個整型的變數,可以採用如下方式表示:
int i = 1;
在Python中,定義整型變數的表達方式更簡練。
i = 1
Python根據變數的值自動判斷變數的類型,程式師不需要關心變數究竟是什麼類型,只要知道創建的變數中存放了一個數,以後的工作只是對這個數值進行操作,Python會對這個數的生命週期負責。
更重要的一點是,C或Java只是創建了一個int型的普通變數;而Python創建的是一個整型物件,並且Python自動完成了整型物件的創建工作,不再需要通過構造函數創建。Python內部沒有普通類型,任何類型都是對象。如果C或Java需要修改變數i的值,只要重新賦值即可;而Python並不能修改對象i的值。例如:
01
#下麵的兩個i並不是同一個對象
02
i = 1
03
print(id(i))
04
i = 2
05
print (id(i))
如果需要查看變數的類型,可以使用Python定義的type類。type是__builtin__模組的一個類,該類能返回變數的類型或創建一個新的類型。__builtin__模組是Python的內聯模組,內聯模組不需要import語句,由Python解譯器自動導入。後面還會接觸到更多內聯模組的類和函數。
下面這段代碼返回了各種變數的類型。
01
#整型
02
i = 1
03
print( type(i))
04
#長整型
05
l = 999999999999999999990 # 什麼時候python將int轉為float跟作業系統位元數相關
06
print type(l)
07
#浮點型
08
f = 1.2
09
print( type(f))
10
#布林型
11
b = True
12
print (type(b))
【代碼說明】
·第3行代碼輸出結果:
·第6行代碼輸出結果:
·第9行代碼輸出結果:
·第12行代碼輸出結果:
用Python來進行科學計算也很方便,因為Python內置了複數類型。Java、C#等高階語言則沒有提供複數類型。
01
#複數類型
02
c = 7 + 8j
03
print (type(c))
第3行代碼輸出結果:<class'complex'>
注意 複數類型的寫法與數學中的寫法相同,如果寫為c=7+8i,Python不能識別其中的“i”,將提示語法錯誤。
2.4.2 字串
在Python中有3種表示字串的方式——單引號、雙引號、三引號。單引號和雙引號的作用是一樣的,對於不同的程式師可以根據自己的習慣使用單引號或雙引號。PHP程式師可能更習慣使用單引號表示字串,C、Java程式師則習慣使用雙引號表示字串。下面這段代碼中單引號和雙引號的使用是等價的。
01
# 單引號和雙引號的使用是等價的
02
str = "hello world!"
03
print (str)
04
str = 'hello world!'
05
print (str)
【代碼說明】 第3行代碼輸出結果:
hello world!
第5行代碼輸出結果:
hello world!
三引號的用法是Python特別的語法,三引號中可以輸入單引號、雙引號或換行等字元。
01
# 三引號的用法
02
str = '''he say "hello world!"'''
03
print( str)
【代碼說明】 第3行代碼的三引號中帶有雙引號,雙引號也會被輸出。輸出結果:
he say "hello world!"
三引號的另一種用法是製作文檔字串。Python的每個物件都有一個屬性__doc__,這個屬性用於描述該物件的作用。
01
# 三引號製作doc文檔
02
class Hello:
03 '''hello class'''
04 def printHello():
05 '''print hello world'''
06 print ("hello world!")
07
print( Hello.__doc__)
08
print (Hello.printHello.__doc__)
【代碼說明】
·第2行代碼定義了一個名為Hello的類。
·第3行是對Hello類的描述,該字串將被存放在類的__doc__屬性中。
·第4行代碼定義了一個方法printHello()。
·第5行代碼描述了printHello(),並把字串存放在該函數的__doc__屬性中。
·第6行代碼輸出結果:
hello world!
·第7行代碼輸出Hello的__doc__屬性的內容。輸出結果:
hello class
·第8行代碼輸出printHello()的__doc__屬性的內容。輸出結果:
print hello world
如果要輸出含有特殊字元(單引號、雙引號等)的字串,需要使用轉義字元。Python中轉義字元為“\”,和C、Java中的轉義字元相同。轉義操作只要在特殊字元的前面加上“\”即可。下面這段代碼說明了特殊字元的轉義用法。
01
# 轉義字元
02
str = 'he say:\'hello world!\''
03
print (str)
【代碼說明】 第2行代碼中的單引號是特殊字元,需要在“'”前加上轉義字元。第3行代碼的輸出結果:
he say:'hello world!'
使用雙引號或三引號可以直接輸出含有特殊字元的字串,不需要使用轉義字元。
01
# 直接輸出特殊字元
02
str = "he say:'hello world!'"
03
print (str)
04
str = '''he say:'hello world!' '''
05
print (str)
【代碼說明】
·第2行代碼中使用了雙引號表示字串變數str,因此Python能夠識別出雙引號內部的單引號只是作為輸出的字元。
·第3行代碼的輸出結果:
he say:'hello world!'
·第4行代碼使用三引號表示字串變數str,注意最後一個單引號後面留有一個空格,這個空格是為了讓Python識別出三引號留下的。如果不留下這個空格,4個單引號連在一起,Python解譯器不能正確識別三引號。提示如下錯誤:
SyntaxError: EOL while scanning
single-quoted string
·第5行代碼的輸出結果:
he say:'hello world!'
注意 輸出的字串中含有單引號,使用雙引號表示字串即可。相反,輸出的字串中含有雙引號時,可使用單引號表示字串。
2.5 運算子與運算式
01
print( "1 + 1 =", 1 + 1)
02
print ("2 - 1 =", 2 - 1)
03
print( "2 * 3 =", 2 * 3)
04
print ("4 / 2 =", 4 / 2)
05
print( "1 / 2 =", 1 / 2)
06
print ("1 / 2 =", 1.0 / 2.0)
07
print ("3 % 2 =", 3 % 2)
08
print ("2 ** 3 =", 2 ** 3)
【代碼說明】
·第1行代碼的輸出結果:1+1=2
·第2行代碼的輸出結果:2-1=1
·第3行代碼的輸出結果:2*3=6
·第4行代碼的輸出結果:4/2=2
·第5行代碼的輸出結果:1/2=0.5
·第6行代碼中的被除數是1.0,除數是2.0。Python把這兩個數作為浮點型處理,因此相除後可以得到正確的結果。輸出結果:1.0/2.0=0.5
·第7行代碼中,求模的值為3除以2後的餘數。輸出結果:3%2=1
·第8行代碼的輸出結果:2**3=8
注意 Python2中執行“1/2”算術運算式的結果略有不同,Python2認為1和2是整型,相除後的結果會被截斷,因此得到的值為0。
Python的算術運算式具有結合性和優先性。結合性是指運算式按照從左往右、先乘除後加減的原則。即從運算式的左邊開始計算,先執行乘法和除法運算,再執行加法和減法運算。例如:
a + b * c % d
以上運算式先執行b*c,然後執行b*c%d,最後執行加法運算。
優先性是指先執行圓括號內的運算式,再按照結合性的原則進行計算。例如:
(a + b) * (c % d)
以上運算式先計算a+b的值,然後計算c%d的值,最後把兩個值相乘。下面這段代碼演示了算數運算的優先順序。
01
# 算數運算的優先順序
02
a = 1
03
b = 2
04
c = 3
05
d = 4
06
print ("a + b * c % d =", a + b * c % d)
07
print ("(a + b) * (c % d) =", (a + b) * (c % d))
第6行代碼的輸出結果:
a + b * c % d = 3
第7行代碼的輸出結果:
(a + b) * (c % d) = 9
2.5.2 關係運算子和關聯運算式
關係運算子即對兩個物件進行比較的符號。Python中的關係運算子和運算式如表2-3所示。
01
# 關聯運算式
02
print (2 > 1)
03
print (1 <= 2)
04
print (1 == 2)
05
print (1 != 2)
【代碼說明】
·第2行代碼,2>1的邏輯正確。輸出結果:True
·第3行代碼,1<=2的邏輯正確。輸出結果:True
·第4行代碼,1==2的邏輯錯誤。輸出結果:False
·第5行代碼,1!=2的邏輯正確。輸出結果:True
不同的關係運算子優先順序別不同。其中<、<=、>、>=4個運算子的優先順序別相等,==、!=的優先順序別相等。而<、<=、>、>=的優先順序別大於==、!=的優先順序別。例如:a>=b==c等價於(a>=b)==c。
關係運算子的優先順序低於算術運算子。下面的代碼演示了關係運算子的優先順序別。
01
# 關聯運算式的優先順序別
02
print( "1 + 2 < 3 - 1 =>", 1 + 2, "<", 3 -
1, "=>", 1 + 2 < 3 - 1)
03
print ("1 + 2 <= 3 > 5 % 2 =>", 1 + 2,
"<=", 3, ">", 5 % 2, "=>", 1 + 2 <= 3
> 5 % 2)
【代碼說明】
·第2行代碼,先執行1+2=3,然後執行3–1=2,最後比較3<2。輸出結果:
1 + 2 < 3 - 1 => 3 < 2 =>
False
·第3行代碼,先執行1+2=3,然後執行5%2=1,最後比較3<=3>1。輸出結果:
1 + 2 <= 3 > 5 % 2 => 3 <= 3
> 1 => True
2.5.3 邏輯運算子和邏輯運算式
邏輯運算式是用邏輯運算子和變數連接起來的式子。任何語言的邏輯運算子都只有3種——邏輯與、邏輯或和邏輯非。C、Java語言的邏輯運算子用&&、||、!表示,Python採用and、or、not表示。表2-4列出了Python中的邏輯運算子和運算式。
表2-4 Python中的邏輯運算子和運算式
01
# 邏輯運算子
02
print( not True)
03
print( False and True)
04
print (True and False)
05
print (True or False)
【代碼說明】
·第2行代碼,True的邏輯非為False。輸出結果:False
·第3行代碼,檢測到and運算子左側的False,就直接返回False。輸出結果:False
·第4行代碼,檢測到and運算子左側為True,然後繼續檢測右側,右側的值為False,於是返回False。輸出結果:False
·第5行代碼,or運算子的左側為True,於是返回True。輸出結果:True
邏輯非的優先順序大於邏輯與和邏輯或的優先順序,而邏輯與和邏輯或的優先順序相等。邏輯運算子的優先順序低於關係運算子,必須先計算關係運算子,然後再計算邏輯運算子。下面這段代碼演示了邏輯運算子、關係運算子和算術運算子的優先順序別。
01
# 邏輯運算式的優先順序別
02
print( "not 1 and 0 =>", not 1 and 0)
03
print( "not (1 and 0) =>", not (1 and 0))
04
print ("(1 <= 2) and
False or True =>", (1 <= 2) and False or True)
05
print ("(1 <= 2) or 1 > 1 + 2 =>", 1 <= 2,
"or", 1 > 2, "=>", (1 <= 2) or (1 < 2))
【代碼說明】
·第2行代碼,先執行not 1,再執行and運算。輸出結果:
not 1 and 0 => False
·第3行代碼,先執行括弧內的1 and
0,再執行not運算。輸出結果:
not (1 and 0) => True
·第4行代碼,先執行1<=2的關係運算運算式,再執行and運算,最後執行or運算。輸出結果:
(1 <= 2) and False or True => True
·第5行代碼,先執行1<=2的關係運算運算式,再執行運算式1>1+2,最後執行or運算。輸出結果:
(1 <= 2) or 1 > 1 + 2 => True
or False => True







0 留言:
發佈留言