一、Python複習教程(重點)- 基礎

花開如雨發表於2020-10-26

目錄導航:

文章目錄

一、Python基礎

1.1 Python安裝和使用

1.1.1 Python環境搭建

  • Python可應用於多平臺包括Windows、 Linux/Unix 和 Mac OS。

Python下載

  • Python最新原始碼,二進位制文件,新聞資訊等可以在Python的官網檢視到:
  • Python官網:http://www.python.org/
  • 你可以在以下連結中下載 Python 的文件,你可以下載 HTML、PDF 和 PostScript 等格式的文件。
  • Python文件下載地址:www.python.org/doc/

Unix & Linux 平臺安裝 Python:(原始碼式安裝)

  • 以下為在Unix & Linux 平臺上安裝 Python 的簡單步驟:
    • 開啟WEB瀏覽器訪問http://www.python.org/download/
    • 選擇適用於Unix/Linux的原始碼壓縮包。
    • 下載及解壓壓縮包。
    • 如果你需要自定義一些選項修改Modules/Setup
    • 執行 ./configure 指令碼
    • make
    • make install
  • 執行以上操作後,Python會安裝在 /usr/local/bin 目錄中,Python庫安裝在/usr/local/lib/pythonXX,XX為你使用的Python的版本號。

通過ubuntu官方的apt工具包安裝

   $ sudo apt-get install python  
   $ sudo apt-get install python2.7  
   $ sudo apt-get install python3.6

Mac安裝Python3

   $ brew sreach python
   $ brew install python3
   //在/usr/local/Cellar/這個目錄下

Windows下直接下載安裝就可以了

  • 首先訪問http://www.python.org/download/去下載最新的python版本
  • 安裝下載包,一路next,注意選擇安裝pip

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-ftBqZi0g-1603700619101)(https://edu.csdn.net/notebook/python/images/week01/2017-12-14_191451.png)]

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-oEopZozG-1603700619103)(https://edu.csdn.net/notebook/python/images/week01/2017-12-14_191544.png)]

  • 為計算機新增安裝目錄搭到環境變數,如圖把python的安裝目錄新增到pth系統變數中即可。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-L0gzjcFX-1603700619105)(https://edu.csdn.net/notebook/python/images/week01/11.png)]

1.1.2 執行Python

  • 有三種方式可以執行Python:

(1) 互動式直譯器

  • 你可以通過命令列視窗進入python並開在互動式直譯器中開始編寫Python程式碼。
  • 你可以在Unix,DOS或任何其他提供了命令列或者shell的系統進行python編碼工作。
$ python # Unix/Linux 

或者 

C:>python # Windows/DOS
  • 以下為Python命令列引數:
選項描述
-d在解析時顯示除錯資訊
-O生成優化程式碼 ( .pyo 檔案 )
-S啟動時不引入查詢Python路徑的位置
-V輸出Python版本號
-X從 1.6版本之後基於內建的異常(僅僅用於字串)已過時。
-c cmd執行 Python 指令碼,並將執行結果作為 cmd 字串。
file在給定的python檔案執行python指令碼。

(2) 命令列指令碼

  • 在你的應用程式中通過引入直譯器可以在命令列中執行Python指令碼,如下所示:
$ python script.py # Unix/Linux 

或者 

C:>python script.py # Windows/DOS

(3) 整合開發環境(IDE:Integrated Development Environment): PyCharm

  • PyCharm 是由 JetBrains 打造的一款 Python IDE,支援 macOS、 Windows、 Linux 系統。
  • PyCharm 功能 : 除錯、語法高亮、Project管理、程式碼跳轉、智慧提示、自動完成、單元測試、版本控制……
  • PyCharm 下載地址 : https://www.jetbrains.com/pycharm/download/

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-gTvmmpiH-1603700619107)(https://edu.csdn.net/notebook/python/images/week01/22.png)]

1.2 Python基礎語法

1.2.1 輸入和輸出

input()輸入:

  • input()的小括號中放入的是,提示資訊,用來在獲取資料之前給使用者的一個簡單提示
  • input()在從鍵盤獲取了資料以後,會存放到等號右邊的變數中
  • input()會把使用者輸入的任何值都作為字串來對待
  • 注意:在python2中還有一個raw_input()輸入,但到python3中沒有了
#!/usr/bin/python3

str = input("請輸入:");
print ("你輸入的內容是: ", str)
  • 這會產生如下的對應著輸入的結果:
請輸入:Hello Python!
你輸入的內容是:  Hello Python!

Print()輸出:

  • print 預設輸出是換行的,如果要實現不換行需要在變數末尾加上 end="":
#!/usr/bin/python3

x="a"
y="b"
# 換行輸出
print( x )
print( y )

print('---------')
# 不換行輸出
print( x, end=" " )
print( y, end=" " )
print()

# 同時輸出多個變數
print(x,y)

format的格式化函式(瞭解)

  • 格式化字串的函式 str.format(),它增強了字串格式化的功能。
  • 基本語法是通過 {} 和 : 來代替以前的 % 。
>>>"{} {}".format("hello", "world")    # 不設定指定位置,按預設順序
'hello world'

>>> "{0} {1}".format("hello", "world")  # 設定指定位置
'hello world'

>>> "{1} {0} {1}".format("hello", "world")  # 設定指定位置
'world hello world'

>>> print("網站名:{name}, 地址 {url}".format(name="百度", url="www.baidu.com")) #指定引數名
'網站名:百度, 地址 www.baidu.com'


>>>site = {"name": "百度", "url": "www.baidu.com"}
>>>print("網站名:{name}, 地址 {url}".format(**site)) # 通過字典設定引數
'網站名:百度, 地址 www.baidu.com' 

>>>my_list = ['百度', 'www.baidu.com']
>>>print("網站名:{0[0]}, 地址 {0[1]}".format(my_list))  # "0" 是必須的 通過列表索引設定引數
'網站名:百度, 地址 www.baidu.com'

>>> print("{:.2f}".format(3.1415926)); #數字格式化
3.14
數字格式輸出描述
3.1415926{:.2f}3.14保留小數點後兩位
3.1415926{:+.2f}+3.14帶符號保留小數點後兩位
-1{:+.2f}-1.00帶符號保留小數點後兩位
2.71828{:.0f}3不帶小數
5{:0>2d}05數字補零 (填充左邊, 寬度為2)
5{:x<4d}5xxx數字補x (填充右邊, 寬度為4)
10{:x<4d}10xx數字補x (填充右邊, 寬度為4)
1000000{:,}1,000,000以逗號分隔的數字格式
0.25{:.2%}25.00%百分比格式
1000000000{:.2e}1.00e+09指數記法
13{:10d}13右對齊 (預設, 寬度為10)
13{:<10d}13左對齊 (寬度為10)
13{:^10d}13中間對齊 (寬度為10)
11‘{:b}’.format(11) ‘{:d}’.format(11) ‘{?}’.format(11) ‘{:x}’.format(11) ‘{:#x}’.format(11) ‘{:#X}’.format(11)1011 11 13 b 0xb 0XB進位制

1.2.2 註釋

Python中的註釋有單行註釋和多行註釋:

  • python中單行註釋採用 # 開頭。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 檔名:test.py

# 第一個註釋
print "Hello, Python!";  # 第二個註釋

輸出結果:

Hello, Python!

註釋可以在語句或表示式行末:

name = "Madisetti" # 這是一個註釋
  • python 中多行註釋使用三個單引號(’’’)或三個雙引號(""")。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 檔名:test.py

'''
這是多行註釋,使用單引號。
這是多行註釋,使用單引號。
這是多行註釋,使用單引號。
'''

"""
這是多行註釋,使用雙引號。
這是多行註釋,使用雙引號。
這是多行註釋,使用雙引號。
"""

1.2.3 識別符號

  • Python裡,識別符號: 由字母、數字、下劃線組成,但不能以數字開頭

  • Python 中的識別符號是區分大小寫的。

  • 特殊識別符號:

    • 以下劃線開頭的識別符號是有特殊意義的。以單下劃線開頭 _foo 的代表不能直接訪問的類屬性,需通過類提供的介面進行訪問,不能用 from xxx import * 而匯入;
    • 以雙下劃線開頭的 __foo 代表類的私有成員;以雙下劃線開頭和結尾的 __foo__ 代表 Python 裡特殊方法專用的標識,如 __init__() 代表類的建構函式。
  • python保留字: 保留字即關鍵字,我們不能把它們用作任何識別符號名稱。Python 的標準庫提供了一個 keyword 模組,可以輸出當前版本的所有關鍵字:

    >>> import keyword
    >>> keyword.kwlist
    ['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 
    'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 
    'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'if',
    'return','try', 'while', 'with', 'yield']
    

1.2.4 變數

  • Python 中的變數不需要宣告。每個變數在使用前都必須賦值,變數賦值以後該變數才會被建立。
  • 在 Python 中,變數就是變數,它沒有型別,我們所說的"型別"是變數所指的記憶體中物件的型別。
  • 等號(=)用來給變數賦值。
  • 等號(=)運算子左邊是一個變數名,等號(=)運算子右邊是儲存在變數中的值。例如:
  • 例項(Python 3.0+)
#!/usr/bin/python3

counter = 100          # 整型變數
miles   = 1000.0       # 浮點型變數
name    = "demo"     # 字串

print (counter)
print (miles)
print (name)
  • 執行以上程式會輸出如下結果:

    100
    1000.0
    demo
    

多個變數賦值

  • Python允許你同時為多個變數賦值。例如:

    a = b = c = 1
    
  • 以上例項,建立一個整型物件,值為1,三個變數被分配到相同的記憶體空間上。

  • 您也可以為多個物件指定多個變數。例如:

    a, b, c = 1, 2, "demo"
    
  • 以上例項,兩個整型物件 1 和 2 的分配給變數 a 和 b,字串物件 “demo” 分配給變數 c。

1.2.5 行與縮排

  • python最具特色的就是使用縮排來表示程式碼塊,不需要使用大括號({})。
  • 縮排的空格數是可變的,但是同一個程式碼塊的語句必須包含相同的縮排空格數。例項如下:
if True:
    print ("True")
else:
    print ("False")
  • 以下程式碼最後一行語句縮排數的空格數不一致,會導致執行錯誤:
if True:
    print ("Answer")
    print ("True")
else:
    print ("Answer")
  print ("False")    # 縮排不一致,會導致執行錯誤
  • 以上程式由於縮排不一致,執行後會出現類似以下錯誤:
 File "test.py", line 6
    print ("False")    # 縮排不一致,會導致執行錯誤
                                      ^
IndentationError: unindent does not match any outer indentation level

多行語句

  • Python 通常是一行寫完一條語句,但如果語句很長,我們可以使用反斜槓()來實現多行語句,例如:
total = item_one + \
        item_two + \
        item_three
  • 在 [], {}, 或 () 中的多行語句,不需要使用反斜槓(),例如:
total = ['item_one', 'item_two', 'item_three',
        'item_four', 'item_five']

空行

  • 函式之間或類的方法之間用空行分隔,表示一段新的程式碼的開始。類和函式入口之間也用一行空行分隔,以突出函式入口的開始。
  • 空行與程式碼縮排不同,空行並不是Python語法的一部分。書寫時不插入空行,Python直譯器執行也不會出錯。但是空行的作用在於分隔兩段不同功能或含義的程式碼,便於日後程式碼的維護或重構。
  • 記住:空行也是程式程式碼的一部分。

1.3 Python運算子

  • 本章節主要說明Python的運算子。舉個簡單的例子 4 +5 = 9 。 例子中,4 和 5 被稱為運算元,"+" 稱為運算子。
  • Python語言支援以下型別的運算子:
    1. 算術運算子
    2. 比較(關係)運算子
    3. 賦值運算子
    4. 邏輯運算子
    5. 位運算子
    6. 成員運算子
    7. 身份運算子
    8. 運算子優先順序

(1) Python算術運算子

  • 以下假設變數a為10,變數b為21:
運算子描述例項
+加 - 兩個物件相加a + b 輸出結果 31
-減 - 得到負數或是一個數減去另一個數a - b 輸出結果 -11
*乘 - 兩個數相乘或是返回一個被重複若干次字串a * b 輸出結果 210
/除 - x 除以 yb / a 輸出結果 2.1
%取模 - 返回除法的餘數b % a 輸出結果 1
**冪 - 返回x的y次冪a**b 為10的21次方
//取整除 - 返回商的整數部分9//2 輸出結果 4 , 9.0//2.0 輸出結果 4.0

(2) Python比較運算子

  • 以下假設變數a為10,變數b為20:
運算子描述例項
==等於 - 比較物件是否相等(a == b) 返回 False。
!=不等於 - 比較兩個物件是否不相等(a != b) 返回 True。
>大於 - 返回x是否大於y(a > b) 返回 False。
<小於 - 返回x是否小於y。返回1表示真,返回0表示假。 這分別與特殊的變數True和False等價。注意,這些變數名的大寫。(a < b) 返回 True。
>=大於等於 - 返回x是否大於等於y。(a >= b) 返回 False。
<=小於等於 - 返回x是否小於等於y。(a <= b) 返回 True。

(3) Python賦值運算子

  • 以下假設變數a為10,變數b為20:
運算子描述例項
=簡單的賦值運算子c = a + b 將 a + b 的運算結果賦值為 c
+=加法賦值運算子c += a 等效於 c = c + a
-=減法賦值運算子c -= a 等效於 c = c - a
*=乘法賦值運算子c *= a 等效於 c = c * a
/=除法賦值運算子c /= a 等效於 c = c / a
%=取模賦值運算子c %= a 等效於 c = c % a
**=冪賦值運算子c **= a 等效於 c = c ** a
//=取整除賦值運算子c //= a 等效於 c = c // a

(4) Python位運算子

  • 按位運算子是把數字看作二進位制來進行計算的。Python中的按位運演算法則如下:
  • 下表中變數 a 為 60,b 為 13二進位制格式如下:
>>> a=18        
>>> bin(a)      # 將變數a的數值轉成二進位制數值輸出
'0b10010'

>>> b = 0b10010  #將二進位制的數值賦給變數b
>>> b
18

# 下面是二進位制運算
a = 0011 1100
b = 0000 1101
-----------------
a&b = 0000 1100
a|b = 0011 1101
a^b = 0011 0001
~a  = 1100 0011
運算子描述例項
&按位與運算子:參與運算的兩個值,如果兩個相應位都為1,則該位的結果為1,否則為0(a & b) 輸出結果 12 ,二進位制解釋: 0000 1100
l按位或運算子:只要對應的二個二進位有一個為1時,結果位就為1。(a l b) 輸出結果 61 ,二進位制解釋: 0011 1101
^按位異或運算子:當兩對應的二進位相異時,結果為1(a ^ b) 輸出結果 49 ,二進位制解釋: 0011 0001
~按位取反運算子:對資料的每個二進位制位取反,即把1變為0,把0變為1。~x 類似於 -x-1(~a ) 輸出結果 -61 ,二進位制解釋: 1100 0011, 在一個有符號二進位制數的補碼形式。
<<左移動運算子:運算數的各二進位全部左移若干位,由"<<"右邊的數指定移動的位數,高位丟棄,低位補0。a << 2 輸出結果 240 ,二進位制解釋: 1111 0000
>>右移動運算子:把">>“左邊的運算數的各二進位全部右移若干位,”>>"右邊的數指定移動的位數a >> 2 輸出結果 15 ,二進位制解釋: 0000 1111

(5) Python邏輯運算子

  • Python語言支援邏輯運算子,以下假設變數 a 為 10, b為 20:
運算子邏輯表示式描述例項
andx and y布林"與" - 如果 x 為 False,x and y 返回 False,否則它返回 y 的計算值。(a and b) 返回 20。
orx or y布林"或" - 如果 x 是 True,它返回 x 的值,否則它返回 y 的計算值。(a or b) 返回 10。
notnot x布林"非" - 如果 x 為 True,返回 False 。如果 x 為 False,它返回 True。not(a and b) 返回 False

(6) Python成員運算子

  • 除了以上的一些運算子之外,Python還支援成員運算子,測試例項中包含了一系列的成員,包括字串,列表或元組。
運算子描述例項
in如果在指定的序列中找到值返回 True,否則返回 False。x 在 y 序列中 , 如果 x 在 y 序列中返回 True。
not in如果在指定的序列中沒有找到值返回 True,否則返回 False。x 不在 y 序列中 , 如果 x 不在 y 序列中返回 True。
#!/usr/bin/python3

a = 10
b = 20
list = [1, 2, 3, 4, 5 ];

if ( a in list ):
   print ("1 - 變數 a 在給定的列表中 list 中")
else:
   print ("1 - 變數 a 不在給定的列表中 list 中")

if ( b not in list ):
   print ("2 - 變數 b 不在給定的列表中 list 中")
else:
   print ("2 - 變數 b 在給定的列表中 list 中")

# 修改變數 a 的值
a = 2
if ( a in list ):
   print ("3 - 變數 a 在給定的列表中 list 中")
else:
   print ("3 - 變數 a 不在給定的列表中 list 中")

以上例項輸出結果:

1 - 變數 a 不在給定的列表中 list 中
2 - 變數 b 不在給定的列表中 list 中
3 - 變數 a 在給定的列表中 list 中

(7) Python身份運算子

  • 身份運算子用於比較兩個物件的儲存單元
運算子描述例項
isis是判斷兩個識別符號是不是引用自一個物件x is y, 類似 id(x) == id(y) , 如果引用的是同一個物件則返回 True,否則返回 False
is notis not 是判斷兩個識別符號是不是引用自不同物件x is not y , 類似 id(a) != id(b)。如果引用的不是同一個物件則返回結果 True,否則返回 False。
  • 注: id() 函式用於獲取物件記憶體地址。
#!/usr/bin/python3

a = 20
b = 20

if ( a is b ):
   print ("1 - a 和 b 有相同的標識")
else:
   print ("1 - a 和 b 沒有相同的標識")

if ( id(a) == id(b) ):
   print ("2 - a 和 b 有相同的標識")
else:
   print ("2 - a 和 b 沒有相同的標識")

# 修改變數 b 的值
b = 30
if ( a is b ):
   print ("3 - a 和 b 有相同的標識")
else:
   print ("3 - a 和 b 沒有相同的標識")

if ( a is not b ):
   print ("4 - a 和 b 沒有相同的標識")
else:
   print ("4 - a 和 b 有相同的標識")
  • 以上例項輸出結果:
1 - a 和 b 有相同的標識
2 - a 和 b 有相同的標識
3 - a 和 b 沒有相同的標識
4 - a 和 b 沒有相同的標識

is 與 == 區別:

# is 用於判斷兩個變數引用物件是否為同一個, == 用於判斷引用變數的值是否相等。
>>>a = [1, 2, 3]
>>> b = a
>>> b is a 
True
>>> b == a
True
>>> b = a[:]   # 其中[:]表示複製傳值
>>> b is a
False
>>> b == a
True

(8) Python運算子優先順序

  • 以下表格列出了從最高到最低優先順序的所有運算子:
運算子描述
**指數 (最高優先順序)
~ + -按位翻轉, 一元加號和減號 (最後兩個的方法名為 +@ 和 -@)
* / % //乘,除,取模和取整除
+ -加法減法
>> <<右移,左移運算子
&位 ‘AND’
^ l位運算子
<= < > >=比較運算子
<> == !=等於運算子
= %= /= //= -= += *= **=賦值運算子
is is not身份運算子
in not in成員運算子
not or and邏輯運算子

1.4 Python資料型別

1.4.1 標準資料型別

  • Python3 中有六個標準的資料型別:
    • Number(數字)
      • int
      • bool
      • float
      • complex(複數)
    • String(字串)
    • List(列表)
    • Tuple(元組)
    • Sets(集合)
    • Dictionary(字典)

(1) Number(數字)

  • Python3 支援 int、float、bool、complex(複數)。
  • 在Python 3裡,只有一種整數型別 int,表示為長整型,沒有 python2 中的 Long。
  • 像大多數語言一樣,數值型別的賦值和計算都是很直觀的。
  • 內建的 type() 函式可以用來查詢變數所指的物件型別。
>>> a, b, c, d = 20, 5.5, True, 4+3j
>>> print(type(a), type(b), type(c), type(d))
<class 'int'> <class 'float'> <class 'bool'> <class 'complex'>
  • 此外還可以用 isinstance 來判斷:
>>>a = 111
>>> isinstance(a, int)
True
>>>
  • isinstance 和 type 的區別在於:
class A:
    pass

class B(A):
    pass

isinstance(A(), A)  # returns True
type(A()) == A      # returns True
isinstance(B(), A)    # returns True
type(B()) == A        # returns False
  • 區別就是:
    • type()不會認為子類是一種父類型別。
    • isinstance()會認為子類是一種父類型別。
注意:在 Python2 中是沒有布林型的,它用數字 0 表示 False,用 1 表示 True。
到 Python3 中,把 True 和 False 定義成關鍵字了,但它們的值還是 1 和 0,它們可以和數字相加。
  • 當你指定一個值時,Number 物件就會被建立:
var1 = 1
var2 = 10
  • 您也可以使用del語句刪除一些物件引用。
    • del語句的語法是:
    • del var1[,var2[,var3[…,varN]]]]
  • 您可以通過使用del語句刪除單個或多個物件。例如
del var
del var_a, var_b

整數的進位制:

# 輸出其他進位制數值

>>> bin(255) #255的二進位制
'0b11111111'
>>> oct(255) #255的八進位制
'0o377'
>>> hex(255) #255的十六進位制
'0xff'

>>> a=0b10   #賦值二進位制數值
>>> a
2
>>> a=0o10   #賦值八進位制數值
>>> a
8
>>> a=0x10   #賦值十六進位制數值
>>> a
16

(2) String(字串)

  • Python中的字串用單引號(’)或雙引號(")括起來,同時使用反斜槓()轉義特殊字元。
  • 字串的擷取的語法格式如下:
    • 變數[頭下標:尾下標]
  • 索引值以 0 為開始值,-1 為從末尾的開始位置。
  • 加號 (+) 是字串的連線符, 星號 (*) 表示複製當前字串,緊跟的數字為複製的次數。例項如下:
#!/usr/bin/python3

str = 'zhangsan'

print (str)          # 輸出字串
print (str[0:-1])    # 輸出第一個到倒數第二個的所有字元
print (str[0])       # 輸出字串第一個字元
print (str[2:5])     # 輸出從第三個開始到第五個的字元
print (str[2:])      # 輸出從第三個開始的後的所有字元
print (str * 2)      # 輸出字串兩次
print (str + "TEST") # 連線字串
  • 輸出結果:
zhangsan
zhangsa
z
ang
angsan
zhangsanzhangsan
zhangsanTEST
  • Python 使用反斜槓()轉義特殊字元,如果你不想讓反斜槓發生轉義,可以在字串前面新增一個r,表示原始字串:
>>> print('Ru\noob')
Ru
oob
>>> print(r'Ru\noob')
Ru\noob
>>>
  • 另外,反斜槓()可以作為續行符,表示下一行是上一行的延續。也可以使用 “”"…""" 或者 ‘’’…’’’ 跨越多行。
  • 注意,Python 沒有單獨的字元型別,一個字元就是長度為1的字串。
>>>word = 'Python'
>>> print(word[0], word[5])
P n
>>> print(word[-1], word[-6])
n P
  • 與 C 字串不同的是,Python 字串不能被改變。向一個索引位置賦值,比如word[0] = 'm’會導致錯誤。
  • 注意:
    • 1、反斜槓可以用來轉義,使用r可以讓反斜槓不發生轉義。
    • 2、字串可以用+運算子連線在一起,用*運算子重複。
    • 3、Python中的字串有兩種索引方式,從左往右以0開始,從右往左以-1開始。
    • 4、Python中的字串不能改變。

(3) List(列表)

  • List(列表) 是 Python 中使用最頻繁的資料型別。
  • 列表可以完成大多數集合類的資料結構實現。列表中元素的型別可以不相同,它支援數字,字串甚至可以包含列表(所謂巢狀)。
  • 列表是寫在方括號[]之間、用逗號分隔開的元素列表。
  • 和字串一樣,列表同樣可以被索引和擷取,列表被擷取後返回一個包含所需元素的新列表。
  • 列表擷取的語法格式如下:
    • 變數[頭下標:尾下標]
  • 索引值以 0 為開始值,-1 為從末尾的開始位置。
  • 加號(+)是列表連線運算子,星號(*)是重複操作。如下例項:
#!/usr/bin/python3

list = [ 'abcd', 786 , 2.23, 'demo', 70.2 ]
tinylist = [123, 'demo']

print (list)            # 輸出完整列表
print (list[0])         # 輸出列表第一個元素
print (list[1:3])       # 從第二個開始輸出到第三個元素
print (list[2:])        # 輸出從第三個元素開始的所有元素
print (tinylist * 2)    # 輸出兩次列表
print (list + tinylist) # 連線列表
  • 以上例項輸出結果:

    ['abcd', 786, 2.23, 'demo', 70.2]
    abcd
    [786, 2.23]
    [2.23, 'demo', 70.2]
    [123, 'demo', 123, 'demo']
    ['abcd', 786, 2.23, 'demo', 70.2, 123, 'demo']
    
  • 與Python字串不一樣的是,列表中的元素是可以改變的:

>>>a = [1, 2, 3, 4, 5, 6]
>>> a[0] = 9
>>> a[2:5] = [13, 14, 15]
>>> a
[9, 2, 13, 14, 15, 6]
>>> a[2:5] = []   # 將對應的元素值設定為 [] 
>>> a
[9, 2, 6]
  • List內建了有很多方法,例如append()、pop()等等,這在後面會講到。

*注意:

* 1、List寫在方括號之間,元素用逗號隔開。
* 2、和字串一樣,list可以被索引和切片。
* 3、List可以使用+操作符進行拼接。
* 4、List中的元素是可以改變的。

(4) Tuple(元組)

  • 元組(tuple)與列表類似,不同之處在於元組的元素不能修改。元組寫在小括號(())裡,元素之間用逗號隔開。
  • 元組中的元素型別也可以不相同:
#!/usr/bin/python3

tuple = ( 'abcd', 786 , 2.23, 'demo', 70.2  )
tinytuple = (123, 'demo')

print (tuple)             # 輸出完整元組
print (tuple[0])          # 輸出元組的第一個元素
print (tuple[1:3])        # 輸出從第二個元素開始到第三個元素
print (tuple[2:])         # 輸出從第三個元素開始的所有元素
print (tinytuple * 2)     # 輸出兩次元組
print (tuple + tinytuple) # 連線元組
  • 以上例項輸出結果:

    ('abcd', 786, 2.23, 'demo', 70.2)
    abcd
    (786, 2.23)
    (2.23, 'demo', 70.2)
    (123, 'demo', 123, 'demo')
    ('abcd', 786, 2.23, 'demo', 70.2, 123, 'demo')
    
  • 元組與字串類似,可以被索引且下標索引從0開始,-1 為從末尾開始的位置。

  • 也可以進行擷取(看上面,這裡不再贅述)。

  • 其實,可以把字串看作一種特殊的元組。

>>>tup = (1, 2, 3, 4, 5, 6)
>>> print(tup[0])
1
>>> print(tup[1:5])
(2, 3, 4, 5)
>>> tup[0] = 11  # 修改元組元素的操作是非法的
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>>
  • 雖然tuple的元素不可改變,但它可以包含可變的物件,比如list列表。
  • 構造包含 0 個或 1 個元素的元組比較特殊,所以有一些額外的語法規則:
tup1 = ()    # 空元組
tup2 = (20,) # 一個元素,需要在元素後新增逗號
string、listtuple都屬於sequence(序列)。
  • 注意:
    • 1、與字串一樣,元組的元素不能修改。
    • 2、元組也可以被索引和切片,方法一樣。
    • 3、注意構造包含0或1個元素的元組的特殊語法規則。
    • 4、元組也可以使用+操作符進行拼接。

(5) Set(集合)

  • 集合(set)是一個無序不重複元素的序列。
  • 基本功能是進行成員關係測試和刪除重複元素。
  • 可以使用大括號 { } 或者set()函式建立集合,注意:建立一個空集合必須用set()而不是 { },因為 { } 是用來建立一個空字典。
  • 建立格式:
parame = {value01,value02,...}
或者
set(value)
  • 例項:
#!/usr/bin/python3

student = {'Tom', 'Jim', 'Mary', 'Tom', 'Jack', 'Rose'}

print(student)   # 輸出集合,重複的元素被自動去掉

# 成員測試
if('Rose' in student) :
    print('Rose 在集合中')
else :
    print('Rose 不在集合中')


# set可以進行集合運算
a = set('abracadabra')
b = set('alacazam')

print(a)

print(a - b)     # a和b的差集

print(a | b)     # a和b的並集

print(a & b)     # a和b的交集

print(a ^ b)     # a和b中不同時存在的元素
  • 以上例項輸出結果:
{'Mary', 'Jim', 'Rose', 'Jack', 'Tom'}
Rose 在集合中
{'b', 'a', 'c', 'r', 'd'}
{'b', 'd', 'r'}
{'l', 'r', 'a', 'c', 'z', 'm', 'b', 'd'}
{'a', 'c'}
{'l', 'r', 'z', 'm', 'b', 'd'}

(6) Dictionary(字典)

  • 字典(dictionary)是Python中另一個非常有用的內建資料型別。
  • 列表是有序的物件結合,字典是無序的物件集合。兩者之間的區別在於:字典當中的元素是通過鍵來存取的,而不是通過偏移存取。
  • 字典是一種對映型別,字典用"{ }"標識,它是一個無序的鍵(key) : 值(value)對集合。
  • 鍵(key)必須使用不可變型別。
  • 在同一個字典中,鍵(key)必須是唯一的。
#!/usr/bin/python3

dict = {}
dict['one'] = "1 - Python教程"
dict[2]     = "2 - Python工具"

tinydict = {'name': 'demo','code':1, 'site': 'www.demo.com'}


print (dict['one'])       # 輸出鍵為 'one' 的值
print (dict[2])           # 輸出鍵為 2 的值
print (tinydict)          # 輸出完整的字典
print (tinydict.keys())   # 輸出所有鍵
print (tinydict.values()) # 輸出所有值

以上例項輸出結果:

1 - Python教程
2 - Python工具
{'name': 'demo', 'site': 'www.demo.com', 'code': 1}
dict_keys(['name', 'site', 'code'])
dict_values(['demo', 'www.demo.com', 1])
  • 建構函式 dict() 可以直接從鍵值對序列中構建字典如下:
  • 例項
>>>dict([('demo', 1), ('Google', 2), ('Taobao', 3)])
{'Taobao': 3, 'demo': 1, 'Google': 2}

>>> {x: x**2 for x in (2, 4, 6)}
{2: 4, 4: 16, 6: 36}

>>> dict(demo=1, Google=2, Taobao=3)
{'Taobao': 3, 'demo': 1, 'Google': 2}
  • 另外,字典型別也有一些內建的函式,例如clear()、keys()、values()等。
  • 注意:
    • 1、字典是一種對映型別,它的元素是鍵值對。
    • 2、字典的關鍵字必須為不可變型別,且不能重複。
    • 3、建立空字典使用 { }。

1.4.2 Python資料型別轉換

  • 有時候,我們需要對資料內建的型別進行轉換,資料型別的轉換,你只需要將資料型別作為函式名即可。
  • 以下幾個內建的函式可以執行資料型別之間的轉換。這些函式返回一個新的物件,表示轉換的值
函式描述
int(x [,base])將x轉換為一個整數
float(x)將x轉換到一個浮點數
complex(real [,imag])建立一個複數
str(x)將物件 x 轉換為字串
repr(x)將物件 x 轉換為表示式字串
eval(str)用來計算在字串中的有效Python表示式,並返回一個物件
tuple(s)將序列 s 轉換為一個元組
list(s)將序列 s 轉換為一個列表
set(s)轉換為可變集合
dict(d)建立一個字典。d 必須是一個序列 (key,value)元組。
frozenset(s)轉換為不可變集合
chr(x)將一個整數轉換為一個字元
unichr(x)將一個整數轉換為Unicode字元
ord(x)將一個字元轉換為它的整數值
hex(x)將一個整數轉換為一個十六進位制字串
oct(x)將一個整數轉換為一個八進位制字串

資料型別轉換分類:

  • 資料型別轉換一共分為2類:自動資料型別轉換(隱式轉換)和強制資料型別轉換(顯示轉換)

自動資料型別轉換/隱式轉換

  • 自動型別轉換是程式根據運算要求進行的轉換,不需要人工干預 1.自動型別轉換不需要人工干預 2.自動型別轉換多發生在運算或者判斷過程中 3.轉化時向著更加精確的型別轉換

強制型別轉換/顯示轉換

  • 根據程式需要,由編寫程式人員人為改變資料型別的方式就是強制資料型別轉換。
  • int() 將其他型別轉化為整型
1.數字整型轉化之後,還是原來的味道
2.浮點型別轉化之後,捨去小數部分
3.布林值轉化之後 True -> 1 False->0
4.字串轉換,僅純整型字串可以轉化(浮點型或者帶有其他字元都不可以轉化)
5.複數不可以轉換
  • float() 將其他型別轉化為浮點型
1.整型轉換之後變為浮點型,後面+.0
2.浮點數不需要轉化,轉化也不會變化
3.布林值轉化 True->1.0  False ->0.0
4.字串,純整型字串和純浮點型字串可以轉換,其他都不可以
  • complex() 將其他資料轉化為複數
1.整型轉換之後變為 (整型+0j2.浮點型轉換之後變為(浮點型 + 0j)
3.布林值轉化之後 True->1+0jFalse(0j)
4.字串,純整型和浮點型字串可以轉化,其他都不行
5.複數,無需轉換
  • bool() 將其他型別轉化為布林值
#下面轉化為布林值false的情況
    1.整型   0
    2.浮點型  0.0
    3.複數  0+0j
    4.布林  False
    5.字串  '' 空字串
    6.列表   [] 空列表
    7.元組   ()空元組
    8.字典   {} 空字典
    9.集合   set() 空集合
  • str() 將其他型別轉化為字串
    • 所有轉換均改變型別為字串,表示方式依舊不變
  • list() 將其他型別轉化為列表型別
    • 在python中有5中可迭代序列,可以互相轉換,他們分別是:
    • 字串,列表,元組,字典,集合
var = ('張三','李四','王老五')

newvar = list(var)

newvar的值為 ['張三','李四','王老五']
  • 注意:
    • 1.字串轉換時每個字元變成列表中的一個值
    • 2.字典型別轉換時,僅將字典的鍵部分轉換成列表,忽略值部分
  • tuple() 將其他型別轉化為元組型別
var = {'張三','李四','王老五'}

newvar = tuple(var)

newvar的值為 ('張三','李四','王老五')
  • 注意:
    
    • 1.字串轉換時每個字元變成元組中的一個值
    • 2.字典型別轉換時,僅將字典的鍵部分轉換成元組,忽略值部分
  • set() 將其他型別轉化為集合型別

var = ['張三','李四','王老五']

newvar = set(var)

newvar的值為 {'張三','李四','王老五'}  #值的順序不定
  • 注意:

    • 1.字串轉換時每個字元變成集合中的一個值
    • 2.字典型別轉換時,僅將字典的鍵部分轉換集合,忽略值部分
  • dict() 將其他型別轉換為字典型別

  • 其他型別轉化為字典時需要按照指定的格式才可以轉化:(列表和元組的組合可以)

[['cat', '黑貓警長'], ['mouse', '一隻耳'], ['next', '請看夏季']]
[('cat', '黑貓警長'),'mouse', '一隻耳','next', '請看夏季']

1.5 Python分支結構

1.5.1 流程控制

  • 流程: 計算機執行程式碼的順序就是流程
  • 流程控制: 對計算機程式碼執行順序的管理就是流程控制
  • 流程分類: 流程控制一共分為三類:
    • 順序結構
    • 分支結構/選擇結構
    • 迴圈結構

1.5.2 分支/選擇結構

  • 分支結構一共分為4類:
    • 單項分支
    • 雙項分支
    • 多項分支
    • 巢狀分支

(1) 單項分支

if 條件表示式:
    一條python語句...
    一條python語句...
    ...
  • 特徵:
    • if條件表示式結果為真,則執行if之後所控制程式碼組,如果為假,則不執行後面的程式碼組(:後面的N行中有相同縮排的程式碼)
    • :之後下一行的內容必須縮排,否則語法錯誤!
    • if之後的程式碼中如果縮排不一致,則不會if條件表示式是的控制,也不是單項分支的內容,是順序結構的一部分
    • if:後面的程式碼是在條件表示式結果為真的情況下執行,所以稱之為真區間或者if區間、

(2) 雙項分支

if 條件表示式:
    一條python語句...
    一條python語句...
    ...
else:
    一條python語句...
    一條python語句...
    ...
  • 特徵:
    • 1.雙項分支有2個區間:分別是True控制的if區間和False控制的else區間(假區間)
    • 2.if區間的內容在雙項分支中必須都縮排,否則語法錯誤!

(2) 多項分支

if 條件表示式:
    一條python語句...
    一條python語句...
    ...
elif 條件表示式:
    一條python語句...
    一條python語句...
    ...
elif 條件表示式:
    一條python語句...
    一條python語句...
    ...
...
else:
    一條python語句...
    一條python語句...
  • 特徵:
    • 1.多項分支可以新增無限個elif分支,無論如何只會執行一個分支
    • 2.執行完一個分支後,分支結構就會結束,後面的分支都不會判斷也不會執行
    • 3.多項分支的判斷順序是自上而下逐個分支進行判斷
    • 4.在Python中沒有switch – case語句。
  • 例項-演示了狗的年齡計算判斷:
#!/usr/bin/python3

age = int(input("請輸入你家狗狗的年齡: "))
print("")
if age < 0:
    print("你是在逗我吧!")
elif age == 1:
    print("相當於 14 歲的人。")
elif age == 2:
    print("相當於 22 歲的人。")
elif age > 2:
    human = 22 + (age -2)*5
    print("對應人類年齡: ", human)

### 退出提示
input("點選 enter 鍵退出")

(4) 巢狀分支

  • 巢狀分支是其他分支結構的巢狀結構,無論哪個分支都可以巢狀
# !/usr/bin/python3

num=int(input("輸入一個數字:"))
if num%2==0:
    if num%3==0:
        print ("你輸入的數字可以整除 2 和 3")
    else:
        print ("你輸入的數字可以整除 2,但不能整除 3")
else:
    if num%3==0:
        print ("你輸入的數字可以整除 3,但不能整除 2")
    else:
        print  ("你輸入的數字不能整除 2 和 3")
  • 將以上程式儲存到 test_if.py 檔案中,執行後輸出結果為:
$ python3 test.py 
輸入一個數字:6
你輸入的數字可以整除 2 和 3

1.6 Python迴圈結構

  • 迴圈結構就是為了將相似或者相同的程式碼操作變得更見簡潔,使得程式碼可以重複利用
  • 迴圈結構分為2類:while迴圈 和 for..in迴圈

1.6.1 while型迴圈

格式1:
    while 條件表示式:
        迴圈的內容
        [變數的變化]

格式2:

    while 條件表示式:
        迴圈的內容
        [變數的變化]
    else:
        python語句..
  • 注意:while迴圈中的else是在while條件表示式為假的情況下執行的程式碼內容,一般用於判斷起始條件是否為假等相關操作。
  • 例項使用了 while 來計算 1 到 100 的總和:
#!/usr/bin/env python3

n = 100
sum = 0
counter = 1
while counter <= n:
    sum = sum + counter
    counter += 1

print("1 到 %d 之和為: %d" % (n,sum))
  • 執行結果如下:
1 到 100 之和為: 5050

死迴圈:

  • 死迴圈就是迴圈不會終止的迴圈型別,通過將用於判斷的條件表示式設定為永遠為True來實現。
    while True:
        python程式碼...
        python程式碼...
        ...
#!/usr/bin/python3

var = 1
while var == 1 :  # 表示式永遠為 true
   num = int(input("輸入一個數字  :"))
   print ("你輸入的數字是: ", num)

print ("Good bye!")
  • 你可以使用 CTRL+C 來退出當前的無限迴圈
  • 執行以上指令碼,輸出結果如下:
輸入一個數字  :5
你輸入的數字是:  5
輸入一個數字  :

1.6.2 for … in 迴圈

  • for…in 迴圈用於遍歷容器類的資料(字串,列表,元組,字典,集合)
格式:

    for  變數  in  容器:
        python程式碼,可以在此使用變數

格式2:

    for 變數1,變數2 in 容器:
        python程式碼,可以在此使用變數1和變數2
  • 要求遍歷的容器必須是一下幾種格式:
    • [(),(),()] 列表中有元組
    • [[],[],[]] 列表中有列表
    • ((),(),()) 元組中有元組
    • {(),(),()} 集合中有元組
    • 字典的特殊使用
格式3:
    for  變數  in  容器:
        python程式碼,可以在此使用變數
    else:
        迴圈結束是執行的程式碼!
>>>languages = ["C", "C++", "Perl", "Python"] 
>>> for x in languages:
...     print (x)
... 
C
C++
Perl
Python
>>>

1.6.3 range()函式

  • 如果你需要遍歷數字序列,可以使用內建range()函式。它會生成數列,例如:
>>>for i in range(5):
...     print(i)
...
0
1
2
3
4
>>>for i in range(5,9) :
    print(i)


5
6
7
8
>>>
>>>for i in range(0, 10, 3) :
    print(i)


0
3
6
9
>>>
>>>for i in range(-10, -100, -30) :
    print(i)

-10
-40
-70
>>>
  • 您可以結合range()和len()函式以遍歷一個序列的索引,如下所示:
>>>a = ['Google', 'Baidu', 'Runoob', 'Taobao', 'QQ']
>>> for i in range(len(a)):
...     print(i, a[i])
... 
0 Google
1 Baidu
2 Runoob
3 Taobao
4 QQ
>>>

輸出乘法口訣:

for i in range(1,10):
    for j in range(1,i+1):
        print(str(i)+'*'+str(j)+"="+str(i*j),end="")
    print()

1.3.7 練習:逆向輸出乘法口訣

for i in range(9,0,-1):
    for j in range(i,0,-1):
        print(str(i)+'*'+str(j)+"="+str(i*j),end="\t")
    print()

1.6.4 break和continue語句及迴圈中的else子句

break語句:

  • break作用:在迴圈中break的作用是終止當前迴圈結構的後續操作,一旦程式執行了break,迴圈也就終止了!
  • break 語句可以跳出 for 和 while 的迴圈體。如果你從 for 或 while 迴圈中終止,任何對應的迴圈 else 塊將不執行。 例項如下:
#!/usr/bin/python3

for letter in 'Runoob':     # 第一個例項
   if letter == 'b':
      break
   print ('當前字母為 :', letter)

var = 10                    # 第二個例項
while var > 0:              
   print ('當期變數值為 :', var)
   var = var -1
   if var == 5:
      break

print ("Good bye!")
  • 執行以上指令碼輸出結果為:
當前字母為 : R
當前字母為 : u
當前字母為 : n
當前字母為 : o
當前字母為 : o
當期變數值為 : 10
當期變數值為 : 9
當期變數值為 : 8
當期變數值為 : 7
當期變數值為 : 6
Good bye!

continue語句:

  • continue語句被用來告訴Python跳過當前迴圈塊中的剩餘語句,然後繼續進行下一輪迴圈。
#!/usr/bin/python3

for letter in 'Runoob':     # 第一個例項
   if letter == 'o':        # 字母為 o 時跳過輸出
      continue
   print ('當前字母 :', letter)

var = 10                    # 第二個例項
while var > 0:              
   var = var -1
   if var == 5:             # 變數為 5 時跳過輸出
      continue
   print ('當前變數值 :', var)
print ("Good bye!")
  • 執行以上指令碼輸出結果為:
當前字母 : R
當前字母 : u
當前字母 : n
當前字母 : b
當前變數值 : 9
當前變數值 : 8
當前變數值 : 7
當前變數值 : 6
當前變數值 : 4
當前變數值 : 3
當前變數值 : 2
當前變數值 : 1
當前變數值 : 0
Good bye!
  • 迴圈語句可以有 else 子句,它在窮盡列表(以for迴圈)或條件變為 false (以while迴圈)導致迴圈終止時被執行,但迴圈被break終止時不執行。
  • 如下例項用於查詢質數的迴圈例子:
#!/usr/bin/python3

for n in range(2, 10):
    for x in range(2, n):
        if n % x == 0:
            print(n, '等於', x, '*', n//x)
            break
    else:
        # 迴圈中沒有找到元素
        print(n, ' 是質數')
  • 執行以上指令碼輸出結果為:
2  是質數
3  是質數
4 等於 2 * 2
5  是質數
6 等於 2 * 3
7  是質數
8 等於 2 * 4
9 等於 3 * 3

pass 語句:

  • Python pass是空語句,是為了保持程式結構的完整性。
  • pass 不做任何事情,一般用做佔位語句,如下例項
>>>while True:
...     pass  # 等待鍵盤中斷 (Ctrl+C)
最小的類:


>>>class MyEmptyClass:
...     pass

1.7 Python函式

1.7.1 認識Python函式

  • 函式的本質就是功能的封裝。使用函式可以大大提高程式設計效率與程式的可讀性。
  • 函式是能夠實現特定功能的計算機程式碼而已,他是一種特定的程式碼組結構。
  • 函式的作用
    • 1.提升程式碼的重複利用率,避免重複開發相同程式碼
    • 2.提高程式開發效率
    • 3.便於程式維護

定義一個函式:

  • 你可以定義一個由自己想要功能的函式,以下是簡單的規則:
    • 函式程式碼塊以 def 關鍵詞開頭,後接函式識別符號名稱和圓括號 ()。
    • 任何傳入引數和自變數必須放在圓括號中間,圓括號之間可以用於定義引數。
    • 函式的第一行語句可以選擇性地使用文件字串—用於存放函式說明。
    • 函式內容以冒號起始,並且縮排。
    • return [表示式] 結束函式,選擇性地返回一個值給呼叫方。不帶表示式的return相當於返回 None。

1.7.2 函式的定義格式

  • 基本函式格式
  • 帶有引數的函式格式
  • 帶有預設值的引數
  • 關鍵字引數
  • 收集引數(帶*)
  • 多種引數混合

(1) 基本函式格式

def  函式名():
    函式功能程式碼...
    函式功能程式碼...
    ...


呼叫函式: 函式名()
  • 特徵:函式定義之後不會自動執行,必須在呼叫函式後函式才會執行.
  • 函式名的命名規則:和變數基本一樣
    • 1.推薦使用英文或者拼音,禁止使用中文
    • 2.可以使用數字,但是不能用數字開頭
    • 3.不可以使用特殊字元,除了_
    • 4.函式名嚴格區分大小寫
    • 5.函式名必須要有意義。
    • 6.不能和系統已經存在的保留關鍵字衝突!
    • 7.禁止使用和系統提供函式相同的函式名
  • 讓我們使用函式來輸出"Hello World!":
>>> def hello() :
   print("Hello World!")


>>> hello()
Hello World!
>>>

(2) 帶有引數的函式格式

def 函式名(引數,引數...):
    函式功能程式碼...
    函式功能程式碼...
    ...


呼叫函式:函式名(引數,引數...)


形參:形式上的引數,宣告函式時()中的引數是形參
實參:實際上的引數,呼叫函式時()中的引數是實參

注意:實參將值傳遞給形參的過程本質上就是簡單的變數賦值僅此而已

  • 更復雜點的應用,函式中帶上引數變數:
#!/usr/bin/python3

# 計算面積函式
def area(width, height):
    return width * height

def print_welcome(name):
    print("Welcome", name)

print_welcome("Python")
w = 4
h = 5
print("width =", w, " height =", h, " area =", area(w, h))
  • 以上例項輸出結果:
Welcome Python
width = 4  height = 5  area = 20
  • 引數須以正確的順序傳入函式。呼叫時的數量必須和宣告時的一樣。
  • 呼叫printme()函式,你必須傳入一個引數,不然會出現語法錯誤:
#!/usr/bin/python3

#可寫函式說明
def printme( str ):
   "列印任何傳入的字串"
   print (str);
   return;

#呼叫printme函式
printme();
  • 以上例項輸出結果:
Traceback (most recent call last):
  File "test.py", line 10, in <module>
    printme();
TypeError: printme() missing 1 required positional argument: 'str'

(3) 帶有預設值的引數

def 函式名(形參=預設值,形參=預設值...):
    函式功能程式碼...
    函式功能程式碼...
    ...

呼叫函式:
    函式名()  呼叫函式時所有形參採用預設值操作
    函式名(實參,實參...) 呼叫時形參使用實參的值而拋棄預設值
  • 注意:在此情況下使用實參值覆蓋原有形參的預設值,本質上就是變數的重新賦值操作
  • 呼叫函式時,如果沒有傳遞引數,則會使用預設引數。以下例項中如果沒有傳入 age 引數,則使用預設值:
#!/usr/bin/python3

#可寫函式說明
def printinfo( name, age = 35 ):
   "列印任何傳入的字串"
   print ("名字: ", name);
   print ("年齡: ", age);
   return;

#呼叫printinfo函式
printinfo( age=50, name="runoob" );
print ("------------------------")
printinfo( name="runoob" );
  • 輸出結果
名字:  runoob
年齡:  50
------------------------
名字:  runoob
年齡:  35

(4) 關鍵字引數

def 函式名(形參=預設值,形參=預設值...):
    函式功能程式碼...
    函式功能程式碼...
    ...

呼叫函式:函式名(形參=實參,形參=實參...)
  • 關鍵字引數就是呼叫函式時,在實參前面指定形參的做法,為了防止引數按照位置傳遞出現的錯誤
  • 關鍵字引數和函式呼叫關係緊密,函式呼叫使用關鍵字引數來確定傳入的引數值。
  • 使用關鍵字引數允許函式呼叫時引數的順序與宣告時不一致,因為 Python 直譯器能夠用引數名匹配引數值。
  • 以下例項在函式 printme() 呼叫時使用引數名:
#!/usr/bin/python3

#可寫函式說明
def printme( str ):
   "列印任何傳入的字串"
   print (str);
   return;

#呼叫printme函式
printme( str = "Python教程");
  • 以上例項輸出結果:
Python教程
  • 以下例項中演示了函式引數的使用不需要使用指定順序:
#!/usr/bin/python3

#可寫函式說明
def printinfo( name, age ):
   "列印任何傳入的字串"
   print ("名字: ", name);
   print ("年齡: ", age);
   return;

#呼叫printinfo函式
printinfo( age=50, name="runoob" );
  • 以上例項輸出結果:
名字:  runoob
年齡:  50

(5). 收集引數

  • 1.非關鍵字收集引數
def 函式名(*引數名):
    函式功能程式碼...
    函式功能程式碼...
    ...

呼叫函式:函式名(實參,實參...)   沒有數量限制
  • 特徵:
    • 1.非關鍵字收集引數,在形參前新增一個*即可
    • 2.非關鍵字收集引數收集實參組成一個元組
    • 3.非關鍵字收集引數,僅收集沒有任何形參接受的非關鍵字實參
    • 4.非關鍵字收集引數和普通的形參可以共存
#!/usr/bin/python3

# 可寫函式說明
def printinfo( arg1, *vartuple ):
   "列印任何傳入的引數"
   print ("輸出: ")
   print (arg1)
   for var in vartuple:
      print (var)
   return;

# 呼叫printinfo 函式
printinfo( 10 );
printinfo( 70, 60, 50 );
  • 以上例項輸出結果:
輸出:
10
輸出:
70
60
50
  • 2.關鍵字收集引數
def 函式名(**引數名):
    函式功能程式碼...
    函式功能程式碼...
    ...

呼叫函式: 函式名(形參=實參,形參=實參...) 沒有數量限制
  • 特徵:
    • 1.關鍵字收集引數,在形參前新增兩個**即可
    • 2.關鍵字收集引數,收集的結果組成一個字典,關鍵字成為字典的鍵,實參成為值
    • 3.關鍵字收集引數,僅收集沒有任何形參接受的關鍵字引數
    • 4.關鍵字引數可以和普通的形參共存
#定義
def func(country,province,**kwargs):
    print(country,province,kwargs)

#使用
func("China","Sichuan",city = "Chengdu", section = "JingJiang")

# 結果
# China Sichuan {'city': 'Chengdu', 'section': 'JingJiang'}

(6) 多種引數混合

  • 定義函式時儘量避免多種引數格式混合(普通引數/非關鍵字引數,關鍵字引數,非關鍵字收集引數,關鍵字收集引數)
    • 1.普通引數(非關鍵字引數)和關鍵字引數必須在兩種收集引數之前
    • 2.非關鍵字收集引數,必須在關鍵字收集引數之前
    • 3.如果多種引數在一起,必須注意進位制引數多次賦值操作(相同賦值賦值之後,關鍵字引數在此賦值!)

**關於返回值的問題

  • 函式根據執行完畢是否可以得到一個結果,將函式分為2個型別:
    • 執行過程函式:print()
      • 函式執行完畢之後,不會有任何結果可以被接受的函式。
    • 具有返回值的函式:id(),type()
      • 函式執行完畢之後,會產生一個結果,可以被變數接受或者使用的函式
格式:

    def 函式名(引數....):
        函式功能程式碼...
        函式功能程式碼...
        ...

        [return 語句]
  • return的特徵:
    • 1.具有return語句的函式稱為具有返回值的函式
    • 2.return可以為當前函式執行完畢返回一個結果,這樣的函式呼叫可以被接受
    • 3.return執行之後,函式則會終止,所有return之後的語句不會被執行
    • 4.一個函式可以書寫多個return語句,但是一般會放入分支結構當中。
    • 5.一個函式如果需要返回多個資料,需要藉助複合資料型別(list,tuple,set,dict)來操作即可!
    • 6.不帶引數值的return語句返回None。之前的例子都沒有示範如何返回數值.
#!/usr/bin/python3

# 可寫函式說明
def sum( arg1, arg2 ):
   # 返回2個引數的和."
   total = arg1 + arg2
   print ("函式內 : ", total)
   return total;

# 呼叫sum函式
total = sum( 10, 20 );
print ("函式外 : ", total)
  • 以上例項輸出結果:
函式內 :  30
函式外 :  30

1.7.3 函式文件

  • 函式文件就是用來檢視當前函式相關資訊介紹的一個特定格式而已。
  • 檢視函式文件的方法:
    help(函式名稱)

        直接輸出顯示函式文件的內容字串

    函式名.__doc__ 

        直接輸出顯示函式文件的內容元字串(轉義字元不轉義)
  • 定義函式的文件:
    def 函式名(引數...):
        '''
            在此處宣告函式文件

        '''

        函式功能程式碼...
        函式功能程式碼...
        。。。

    或者:

    def 函式名(引數...):
        """
            在此處宣告函式文件

        """

        函式功能程式碼...
        函式功能程式碼...
        。。。
  • 注意:函式文件的作用是對函式進行說明,便於閱讀和快速掌握函式的使用,通常函式文件需要具有以下資訊:
    • 函式的作用
    • 函式的引數介紹(個數,資料型別)
    • 函式的返回值(資料和型別)

1.7.4 區域性變數與全域性變數

  • 定義在函式內部的變數擁有一個區域性作用域,定義在函式外的擁有全域性作用域。
  • 區域性變數只能在其被宣告的函式內部訪問,而全域性變數可以在整個程式範圍內訪問。呼叫函式時,所有在函式內宣告的變數名稱都將被加入到作用域中。如下例項:
#!/usr/bin/python3

total = 0; # 這是一個全域性變數
# 可寫函式說明
def sum( arg1, arg2 ):
    #返回2個引數的和."
    total = arg1 + arg2; # total在這裡是區域性變數.
    print ("函式內是區域性變數 : ", total)
    return total;

#呼叫sum函式
sum( 10, 20 );
print ("函式外是全域性變數 : ", total)
  • 以上例項輸出結果:
函式內是區域性變數 :  30
函式外是全域性變數 :  0

1.7.5 函式其他使用

(1) 匿名函式

  • python 使用 lambda 來建立匿名函式。
  • 所謂匿名,意即不再使用 def 語句這樣標準的形式定義一個函式。
  • lambda 只是一個表示式,函式體比 def 簡單很多。
  • lambda的主體是一個表示式,而不是一個程式碼塊。僅僅能在lambda表示式中封裝有限的邏輯進去。
  • lambda 函式擁有自己的名稱空間,且不能訪問自己引數列表之外或全域性名稱空間裡的引數。
  • 雖然lambda函式看起來只能寫一行,卻不等同於C或C++的行內函數,後者的目的是呼叫小函式時不佔用棧記憶體從而增加執行效率。
  • 語法:
  • lambda 函式的語法只包含一個語句,如下:
lambda [arg1 [,arg2,.....argn]]:expression
  • 如下例項:
#!/usr/bin/python3

# 可寫函式說明
sum = lambda arg1, arg2: arg1 + arg2;

# 呼叫sum函式
print ("相加後的值為 : ", sum( 10, 20 ))
print ("相加後的值為 : ", sum( 20, 20 ))
  • 以上例項輸出結果:
相加後的值為 :  30
相加後的值為 :  40

1.8 Python資料型別的操作

1.8.1 Number數字

  • 之前我們已經介紹了Nember型別的基本操作,下面介紹他們的操作函式(瞭解)

數學函式

函式返回值 ( 描述 )
abs(x)返回數字的絕對值,如abs(-10) 返回 10
ceil(x)返回數字的上入整數,如math.ceil(4.1) 返回 5
cmp(x, y)如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1。 Python 3 已廢棄 。使用 使用 (x>y)-(x<y) 替換。
exp(x)返回e的x次冪(ex),如math.exp(1) 返回2.718281828459045
fabs(x)返回數字的絕對值,如math.fabs(-10) 返回10.0
floor(x)返回數字的下舍整數,如math.floor(4.9)返回 4
log(x)如math.log(math.e)返回1.0,math.log(100,10)返回2.0
log10(x)返回以10為基數的x的對數,如math.log10(100)返回 2.0
max(x1, x2,…)返回給定引數的最大值,引數可以為序列。
min(x1, x2,…)返回給定引數的最小值,引數可以為序列。
modf(x)返回x的整數部分與小數部分,兩部分的數值符號與x相同,整數部分以浮點型表示。
pow(x, y)x**y 運算後的值。
round(x [,n])返回浮點數x的四捨五入值,如給出n值,則代表舍入到小數點後的位數。
sqrt(x)返回數字x的平方根。

隨機數函式

函式描述
choice(seq)從序列的元素中隨機挑選一個元素,比如random.choice(range(10)),從0到9中隨機挑選一個整數。
randrange ([start,] stop [,step])從指定範圍內,按指定基數遞增的集合中獲取一個隨機數,基數預設值為1
random()隨機生成下一個實數,它在[0,1)範圍內。
seed([x])改變隨機數生成器的種子seed。如果你不瞭解其原理,你不必特別去設定seed,Python會幫你選擇seed。
shuffle(lst)將序列的所有元素隨機排序
uniform(x, y)隨機生成下一個實數,它在[x,y]範圍內。

三角函式

函式描述
acos(x)返回x的反餘弦弧度值。
asin(x)返回x的反正弦弧度值。
atan(x)返回x的反正切弧度值。
atan2(y, x)返回給定的 X 及 Y 座標值的反正切值。
cos(x)返回x的弧度的餘弦值。
hypot(x, y)返回歐幾里德範數 sqrt(xx + yy)。
sin(x)返回的x弧度的正弦值。
tan(x)返回x弧度的正切值。
degrees(x)將弧度轉換為角度,如degrees(math.pi/2) , 返回90.0
radians(x)將角度轉換為弧度

數學常量

常量描述
pi數學常量 pi(圓周率,一般以π來表示)
e數學常量 e,e即自然常數(自然常數)。

1.8.2 String字串

(1) Python轉義字元

轉義字元描述
(在行尾時)續行符
\反斜槓符號
單引號
"雙引號
\a響鈴
\b退格(Backspace)
\e轉義
\000
\n換行
\v縱向製表符
\t橫向製表符
\r回車
\f換頁
\oyy八進位制數,yy代表的字元,例如:\o12代表換行
\xyy十六進位制數,yy代表的字元,例如:\x0a代表換行
\other其它的字元以普通格式輸出

(2) Python字串運算子

  • 下表例項變數a值為字串 “Hello”,b變數值為 “Python”:
操作符描述例項
+字串連線a + b 輸出結果: HelloPython
*重複輸出字串a*2 輸出結果:HelloHello
[]通過索引獲取字串中字元a[1] 輸出結果 e
[ : ]擷取字串中的一部分a[1:4] 輸出結果 ell
in成員運算子 - 如果字串中包含給定的字元返回 TrueH in a 輸出結果 1
not in成員運算子 - 如果字串中不包含給定的字元返回 TrueM not in a 輸出結果 1
r/R原始字串 - 原始字串:所有的字串都是直接按照字面 的意思來使用,沒有轉義特殊或不能列印的字元。 原始字串除在字串的第一個引號前加上字母"r"(可以大 小寫)以外,與普通字串有著幾乎完全相同的語法。print r’\n’ prints \n 和 print R’\n’ prints \n
%格式字串請看下一節內容。
#!/usr/bin/python3

a = "Hello"
b = "Python"

print("a + b 輸出結果:", a + b)
print("a * 2 輸出結果:", a * 2)
print("a[1] 輸出結果:", a[1])
print("a[1:4] 輸出結果:", a[1:4])

if( "H" in a) :
    print("H 在變數 a 中")
else :
    print("H 不在變數 a 中")

if( "M" not in a) :
    print("M 不在變數 a 中")
else :
    print("M 在變數 a 中")

print (r'\n')
print (R'\n')
  • 以上例項輸出結果為:
a + b 輸出結果: HelloPython
a * 2 輸出結果: HelloHello
a[1] 輸出結果: e
a[1:4] 輸出結果: ell
H 在變數 a 中
M 不在變數 a 中
\n
\n

(3) Python字串格式化

  • Python 支援格式化字串的輸出 。儘管這樣可能會用到非常複雜的表示式,但最基本的用法是將一個值插入到一個有字串格式符 %s 的字串中。
  • 在 Python 中,字串格式化使用與 C 中 sprintf 函式一樣的語法。
#!/usr/bin/python3

print ("我叫 %s 今年 %d 歲!" % ('小明', 10))

# 以上例項輸出結果:
# 我叫 小明 今年 10 歲!

*python字串格式化符號:

符 號描述
%c格式化字元及其ASCII碼
%s格式化字串
%d格式化整數
%u格式化無符號整型
%o格式化無符號八進位制數
%x格式化無符號十六進位制數
%X格式化無符號十六進位制數(大寫)
%f格式化浮點數字,可指定小數點後的精度
%e用科學計數法格式化浮點數
%E作用同%e,用科學計數法格式化浮點數
%g%f和%e的簡寫
%G%f 和 %E 的簡寫
%p用十六進位制數格式化變數的地址
  • 格式化操作符輔助指令:
符號功能
*定義寬度或者小數點精度
-用做左對齊
+在正數前面顯示加號( + )
在正數前面顯示空格
#在八進位制數前面顯示零(‘0’),在十六進位制前面顯示’0x’或者’0X’(取決於用的是’x’還是’X’)
0顯示的數字前面填充’0’而不是預設的空格
%‘%%‘輸出一個單一的’%’
(var)對映變數(字典引數)
m.n.m 是顯示的最小總寬度,n 是小數點後的位數(如果可用的話)
  • Python2.6 開始,新增了一種格式化字串的函式 str.format(),它增強了字串格式化的功能。

(4) Python 的字串內建函式

序號名稱描述
1capitalize()將字串的第一個字元轉換為大寫
2center(width, fillchar)返回一個指定的寬度 width 居中的字串,fillchar 為填充的字元,預設為空格。
3count(str, beg= 0,end=len(string))返回 str 在 string 裡面出現的次數,如果 beg 或者 end 指定則返回指定範圍內 str 出現的次數
4bytes.decode(encoding=“utf-8”, errors=“strict”)Python3 中沒有 decode 方法,但我們可以使用 bytes 物件的 decode() 方法來解碼給定的 bytes 物件,這個 bytes 物件可以由 str.encode() 來編碼返回。
5encode(encoding=‘UTF-8’,errors=‘strict’)以 encoding 指定的編碼格式編碼字串,如果出錯預設報一個ValueError 的異常,除非 errors 指定的是’ignore’或者’replace’
6endswith(suffix, beg=0, end=len(string))檢查字串是否以 obj 結束,如果beg 或者 end 指定則檢查指定的範圍內是否以 obj 結束,如果是,返回 True,否則返回 False.
7expandtabs(tabsize=8)把字串 string 中的 tab 符號轉為空格,tab 符號預設的空格數是 8 。
8find(str, beg=0 end=len(string))檢測 str 是否包含在字串中,如果指定範圍 beg 和 end ,則檢查是否包含在指定範圍內,如果包含返回開始的索引值,否則返回-1
9index(str, beg=0, end=len(string))跟find()方法一樣,只不過如果str不在字串中會報一個異常.
10isalnum()如果字串至少有一個字元並且所有字元都是字母或數字則返 回 True,否則返回 False
11isalpha()如果字串至少有一個字元並且所有字元都是字母則返回 True, 否則返回 False
12isdigit()如果字串只包含數字則返回 True 否則返回 False…
13islower()如果字串中包含至少一個區分大小寫的字元,並且所有這些(區分大小寫的)字元都是小寫,則返回 True,否則返回 False
14isnumeric()如果字串中只包含數字字元,則返回 True,否則返回 False
15isspace()如果字串中只包含空白,則返回 True,否則返回 False.
16istitle()如果字串是標題化的(見 title())則返回 True,否則返回 False
17isupper()如果字串中包含至少一個區分大小寫的字元,並且所有這些(區分大小寫的)字元都是大寫,則返回 True,否則返回 False
18join(seq)以指定字串作為分隔符,將 seq 中所有的元素(的字串表示)合併為一個新的字串
19len(string)返回字串長度
20ljust(width[, fillchar])返回一個原字串左對齊,並使用 fillchar 填充至長度 width 的新字串,fillchar 預設為空格。
21lower()轉換字串中所有大寫字元為小寫.
22lstrip()截掉字串左邊的空格或指定字元。
23maketrans()建立字元對映的轉換表,對於接受兩個引數的最簡單的呼叫方式,第一個引數是字串,表示需要轉換的字元,第二個引數也是字串表示轉換的目標。
24max(str)返回字串 str 中最大的字母。
25min(str)返回字串 str 中最小的字母。
26replace(old, new [, max])把 將字串中的 str1 替換成 str2,如果 max 指定,則替換不超過 max 次。
27rfind(str, beg=0,end=len(string))類似於 find()函式,不過是從右邊開始查詢.
28rindex( str, beg=0, end=len(string))類似於 index(),不過是從右邊開始.
29rjust(width,[, fillchar])返回一個原字串右對齊,並使用fillchar(預設空格)填充至長度 width 的新字串
30rstrip()刪除字串字串末尾的空格.
31split(str="", num=string.count(str))num=string.count(str)) 以 str 為分隔符擷取字串,如果 num 有指定值,則僅擷取 num 個子字串
32splitlines([keepends])按照行(’\r’, ‘\r\n’, \n’)分隔,返回一個包含各行作為元素的列表,如果引數 keepends 為 False,不包含換行符,如果為 True,則保留換行符。
33startswith(str, beg=0,end=len(string))檢查字串是否是以 obj 開頭,是則返回 True,否則返回 False。如果beg 和 end 指定值,則在指定範圍內檢查。
34strip([chars])在字串上執行 lstrip()和 rstrip()
35swapcase()將字串中大寫轉換為小寫,小寫轉換為大寫
36title()返回"標題化"的字串,就是說所有單詞都是以大寫開始,其餘字母均為小寫(見 istitle())
37translate(table, deletechars="")根據 str 給出的表(包含 256 個字元)轉換 string 的字元, 要過濾掉的字元放到 deletechars 引數中
38upper()轉換字串中的小寫字母為大寫
39zfill (width)返回長度為 width 的字串,原字串右對齊,前面填充0
40isdecimal()檢查字串是否只包含十進位制字元,如果是返回 true,否則返回 false。

1.8.3 List列表

  • 序列是Python中最基本的資料結構。序列中的每個元素都分配一個數字 - 它的位置,或索引,第一個索引是0,第二個索引是1,依此類推。
  • 列表操作例項:
#!/usr/bin/python3

# 定義 
list0 = [] # 建立一個空列表 或者  變數 = list()
list1 = ['Google', 'Python', 1997, 2000];
list2 = [1, 2, 3, 4, 5, 6, 7 ];

#輸出
print ("list1[0]: ", list1[0])  # Google
print ("list2[1:5]: ", list2[1:5]) # [2, 3, 4, 5]

#更新其中的值
print ("第三個元素為 : ", list[2])    # 2000
list[2] = 2001
print ("更新後的第三個元素為 : ", list[2])  # 2001

#刪除其中一個元素
del list[2]
print ("刪除第三個元素 : ", list)  #  ['Google', 'Python', 2000]

(1) 列表的遍歷操作:

1.使用for...in 遍歷列表

    for 變數 in 列表:
        使用變數

2.使用while迴圈遍歷列表

    i = 0
    while i<len(列表):
        使用列表中的元素(列表[i])
        i += 1

3.同等長度二級列表的遍歷

    列表 = [[值1,值2],[值1,值2],....]

    for 變數1,變數2 in 列表:
        使用變數1和變數2

    注意:變數1取二級列表中的第一個值,變數2取第二個值
4.非同等長度的二級列表的遍歷

    列表 = [[值1,值2],[值1,值2,值3],[值]...]

    for 變數1 in 列表:
        for 變數2 in 變數1:
            使用變數2(變數2是二級列表中的每個值)

(2) Python列表指令碼操作符

  • 列表對 + 和 的操作符與字串相似。+ 號用於組合列表, 號用於重複列表。
Python 表示式結果描述
len([1, 2, 3])3長度
[1, 2, 3] + [4, 5, 6][1, 2, 3, 4, 5, 6]組合
[‘Hi!’] * 4[‘Hi!’, ‘Hi!’, ‘Hi!’, ‘Hi!’]重複
3 in [1, 2, 3]True元素是否存在於列表中
for x in [1, 2, 3]: print(x, end=" ")1 2 3迭代

(3) Python列表擷取與拼接

  • Python的列表擷取與字串操作型別,如下所示:L=[‘Google’, ‘Python’, ‘Taobao’]
Python表示式 結果描述
L[2]‘Taobao’讀取第三個元素
L[-2]‘Python’從右側開始讀取倒數第二個元素: count from the right
L[1:][‘Python’, ‘Taobao’]輸出從第二個元素開始後的所有元素
  • 使用巢狀列表即在列表裡建立其它列表,例如:
>>>a = ['a', 'b', 'c']
>>> n = [1, 2, 3]
>>> x = [a, n]
>>> x
[['a', 'b', 'c'], [1, 2, 3]]
>>> x[0]
['a', 'b', 'c']
>>> x[0][1]
'b'

(4) Python列表函式&方法

  • Python包含以下函式:
序號函式名稱說明
1len(list)列表元素個數
2max(list)返回列表元素最大值
3min(list)返回列表元素最小值
4list(seq)將元組轉換為列表
  • Python包含以下方法:
序號方法名稱說明
1list.append(obj)在列表末尾新增新的物件
2list.count(obj)統計某個元素在列表中出現的次數
3list.extend(seq)在列表末尾一次性追加另一個序列中的多個值(用新列表擴充套件原來的列表)
4list.index(obj)從列表中找出某個值第一個匹配項的索引位置
5list.insert(index, obj)將物件插入列表
6list.pop(obj=list[-1])移除列表中的一個元素(預設最後一個元素),並且返回該元素的值
7list.remove(obj)移除列表中某個值的第一個匹配項
8list.reverse()反向列表中元素
9list.sort([func])對原列表進行排序
10list.clear()清空列表
11list.copy()複製列表

1.8.4 Tuple元組

  • Python 的元組與列表類似,不同之處在於元組的元素不能修改。
  • 元組使用小括號,列表使用方括號。
  • 元組建立很簡單,只需要在括號中新增元素,並使用逗號隔開即可。
# 定義元組的方式:
tup0 = ()  #定義一個空元組 或者 變數 = tuple()
tup1 = ('Google', 'Python', 1997, 2000)
tup2 = (1, 2, 3, 4, 5 )
tup3 = "a", "b", "c", "d"

# 輸出元組:
print ("tup1[0]: ", tup1[0])       # tup1[0]:  Google
print ("tup2[1:5]: ", tup2[1:5])   # tup2[1:5]:  (2, 3, 4, 5)

# 注意下面這種定義不加逗號,型別為整型
tup4 = (50)
print(type(tup4))  # <class 'int'>

# 正確定義方式加上逗號,型別為元組
tup5 = (50,)
print(type(tup5))  # <class 'tuple'>

# 以下修改元組元素操作是非法的。
# tup1[0] = 100

#元組中的元素值是不允許刪除的,但我們可以使用del語句來刪除整個元組
del tup0;

(1) 元組運算子

  • 與字串一樣,元組之間可以使用 + 號和 * 號進行運算。這就意味著他們可以組合和複製,運算後會生成一個新的元組。
Python 表示式結果描述
len((1, 2, 3))3長度
(1, 2, 3) + (4, 5, 6)(1, 2, 3, 4, 5, 6)組合
(‘Hi!’) * 4(‘Hi!’, ‘Hi!’, ‘Hi!’, ‘Hi!’)重複
3 in (1, 2, 3)True元素是否存在於元組中
for x in (1, 2, 3): print(x, end=" ")1 2 3迭代

(2)元組索引,擷取

  • 因為元組也是一個序列,所以我們可以訪問元組中的指定位置的元素,也可以擷取索引中的一段元素
  • 如下所示:L=(‘Google’, ‘Python’, ‘Taobao’)
Python表示式 結果描述
L[2]‘Taobao’讀取第三個元素
L[-2]‘Python’從右側開始讀取倒數第二個元素: count from the right
L[1:](‘Python’, ‘Taobao’)輸出從第二個元素開始後的所有元素

(3) 元組內建函式

  • Python元組包含了以下內建函式:
序號函式名稱說明
1len(tuple)元組元素個數
2max(tuple)返回元組元素最大值
3min(tuple)返回元組元素最小值
4tuple(seq)將元組轉換為元組
list1= ['Google', 'Taobao', 'Runoob', 'Baidu']

tuple1=tuple(list1)

print(tuple1)

#('Google', 'Taobao', 'Runoob', 'Baidu')

1.8.5 Sets集合

  • 集合(set)是一個無序不重複元素的序列。
  • 基本功能是進行成員關係測試和刪除重複元素。
  • 可以使用大括號 { } 或者 set() 函式建立集合,注意:建立一個空集合必須用 set() 而不是 { },因為 { } 是用來建立一個空字典。
# 集合的定義
set1 = set()  #定義一個空的集合
set2 = {1,2,3}

# 增加一個元素
set1.add(5)  

#增加多個:
set1.update([5,6,7,8])

#刪除某個值
set1.remove(1)

#查:無法通過下標索引

#改:不可變型別無法修改元素

a={10,20,30}
b={20,50}
print(a - b)     # a和b的差集 

print(a | b)     # a和b的並集

print(a & b)     # a和b的交集

print(a ^ b)     # a和b中不同時存在的元素

(1) 集合的遍歷

1.普通序列的遍歷

    for 變數 in 集合:
        使用變數

2.多級集合

    集合 = {(值,值..),(值,值..)。。。}

    for 變數1,變數2 in 集合:

        使用變數1和變數2

(2) 集合的序列函式

  • len() 計算集合的長度
  • max() 獲取集合中的最大值
  • min() 獲取集合中的最小值
  • set() 建立空集合或者將其他資料轉換為集合

(3) 集合中的方法

  • add – 增加集合元素
name = {'d', 's'}
name.add('d')
name
返回結果:{'d', 's'}
name.add('sd')
name
返回結果:{'sd', 'd', 's'}
  • update–更新已有集合
name = {'sd', 'd', 's'}
name.update('df')
name
返回結果:{'sd', 'd', 'f', 's'}
  • remove–移除指定集合元素
name = {'sd','d','s'}
name.remove('s')
返回結果:name
{'sd', 'd'}
  • discard–移除元素
name = {'sd', 'd', 's'}
name.discard('s')
返回結果:name 
        {'sd', 'd'}

# remove移除非成員值會報錯,discard移除非成員值,啥也不錯!
  • clear–清空集合元素
name = {'d', 's'}
name.clear()
name
返回結果:{}
  • copy–淺拷貝
name = {'sd', 'd', 's'}
li = name.copy()
返回結果:li
        {'sd', 'd', 's'}
  • difference – 求差集
name.difference(li)
set()
>>> name.difference()
{'sd', 'd', 's'}
  • union–並集,建立新的物件
name = {'sd', 'd', 's'}
li = {'s', 'd','h'}
name.union(li)
返回結果:{'h', 's', 'd', 'sd'}
  • difference_update—刪除當前set中的所有包含在 new set 裡的元素
li = ('s', 'd')
name = {'sd', 'd', 's'}
name.difference_update(li)
name
返回結果:{'sd'}
  • intersection–取交集,建立新的set集合
li = ('s', 'd')
name = {'sd', 'd', 's'}
name.intersection(li)
返回結果:{'d', 's'}
  • intersection_update–取交集,更新原來的set集合
li = ('s', 'd')
name = {'sd', 'd', 's'}
name.intersection_update(li)
返回結果:{'d', 's'}
  • isdisjoint–判斷沒有交集,返回True,否則,返回False
li = {'s', 'd'}
name = {'sd', 'd', 's'}
name.isdisjoint(li)
  • issubset–判斷是否是子集
li = {'s', 'd'}
name = {'sd', 'd', 's'}
name.issubset(li)  #判斷name是不是li的子集
返回結果:False
li.issubset(name)  #判斷li是不是name的子集
返回結果:True
  • issuperset–判斷是否是父集
li = {'s', 'd'}
name = {'sd', 'd', 's'}
name.issuperset(li)  #判斷name是不是li的父集
返回結果:True
li.issuperset(name)  #判斷li是不是name的父集
返回結果:False
  • pop–移除集合元素
name = {'sd', 'd', 's'}
name.pop()
返回結果:'sd' #同一個集合,刪除集合元素的順序固定
se1 = {'a','s','sb'}
se1.pop()
返回結果:'sb'
  • symmetric_difference–去兩個集合的差集,建立新的set集合物件
name = {'sd', 'd', 's'}
li = {'s', 'd'}
name.symmetric_difference(li)
返回結果:{'sd'}
  • symmetric_difference_update–去兩個集合的差集,更新原來的集合物件
name = {'sd', 'd', 's'}
li = {'s', 'd'}
name.symmetric_difference_update(li)
返回結果:{'sd'}

1.8.6 Dictionary字典

  • 字典是另一種可變容器模型,且可儲存任意型別物件。
  • 字典的每個鍵值(key=>value)對用冒號(:)分割,每個對之間用逗號(,)分割,整個字典包括在花括號({})中 ,格式如下所示:
d = {key1 : value1, key2 : value2 }
  • 鍵必須是唯一的,但值則不必。

(1) 建立字典

1.建立空字典
    變數 = {} 或者 變數 = dict()

2.建立多個元素的字典:
    方法1:
        變數 = {:,:....}

    方法2:
        變數 = dict({:,:....})

    方法3:
        變數 = dict(=,=...)
        注意:該方式鍵作為形參名使用不可以新增引號,必須符合變數規則

    方法4:
        變數 = dict([(,),(,)...])
        變數 = dict([[,],[,]...])
        變數 = dict(((,),(,)...))

    方法5:
        變數 = dict(zip((鍵,鍵...),(,...)))

(2) 字典的基本操作

訪問字典的元素:
    變數[]

新增字典的元素
    變數[新鍵] = 值

修改字典元素
    變數[] = 新值

刪除字典元素
    del 變數[]
  • 案例:
#!/usr/bin/python3

# 定義一個字典
dict = {'Name': 'Python', 'Age': 17, 'Class': 'First'}

# 輸出子典中的資訊
print ("dict['Name']: ", dict['Name']) #Python
print ("dict['Age']: ", dict['Age'])   #17

# 輸出錯誤資訊:KeyError: 'Alice'
#print ("dict['Alice']: ", dict['Alice'])


# 修改和新增內容
dict['Age'] = 18;              # 更新 Age
dict['School'] = "雲課堂"      # 新增資訊

# 刪除資訊
del dict['Name'] # 刪除鍵 'Name'一個元素值
dict.clear()     # 清空字典
del dict         # 刪除字典

字典的遍歷:

1.鍵的遍歷
    for 變數i in 字典:
        使用i遍歷所有的鍵,有鍵就可以通過變數訪問其值

2.鍵值遍歷
    for 變數i,變數j in 字典.items():
        使用變數i遍歷所有鍵,通過變數j遍歷所有值

字典內涵/字典推導式:

1.普通的字典內涵
    變數= {key:value for key,value in 字典.items()}

2.帶有判斷條件的字典內涵
    變數= {key:value for key,value in 字典.items() if 條件表示式}

3,多個迴圈的字典內涵
    變數 = {i+x:j+y for i,j in 字典1.items for x,y in 字典2.items()}

4.帶有判斷條件的多個迴圈的字典內涵
    變數 = {i+x:j+y for i,j in 字典1.items for x,y in 字典2.items() if 條件表示式}

字典內建函式&方法:

  • Python字典包含了以下內建函式:
序號函式名稱描述例項
1len(dict)計算字典元素個數, 即鍵的總數。>>> dict = {‘Name’: ‘py’, ‘Age’: 7, ‘Class’: ‘First’} >>> len(dict) 3
2str(dict)輸出字典, 以可列印的字串表示。>>> dict = {‘Name’: ‘py’, ‘Age’: 7, ‘Class’: ‘First’} >>> str(dict) “{‘Name’: ‘py’, ‘Class’: ‘First’, ‘Age’: 7}”
3type(variable)返回輸入的變數型別, 如果變數是字典 就返回字典型別。>>> dict = {‘Name’: ‘py’, ‘Age’: 7, ‘Class’: ‘First’} >>> type(dict) <class ‘dict’>
  • Python字典包含了以下內建方法:
序號方法名稱描述
1radiansdict.clear()刪除字典內所有元素
2radiansdict.copy()返回一個字典的淺複製
3radiansdict.fromkeys()建立一個新字典,以序列seq中元素做字典的鍵,val為字典所有鍵對應的初始值
4radiansdict.get(key, default=None)返回指定鍵的值,如果值不在字典中返回default值
5key in dict如果鍵在字典dict裡返回true,否則返回false
6radiansdict.items()以列表返回可遍歷的(鍵, 值) 元組陣列
7radiansdict.keys()以列表返回一個字典所有的鍵
8radiansdict.setdefault(key, default=None)和get()類似, 但如果鍵不存在於字典中,將會新增鍵並將值設為default
9radiansdict.update(dict2)把字典dict2的鍵/值對更新到dict裡
10radiansdict.values()以列表返回字典中的所有值
11pop(key[,default])刪除字典給定鍵 key 所對應的值,返回值為被刪除的值。key值必須給出。 否則,返回default值。
12popitem()隨機返回並刪除字典中的一對鍵和值(一般刪除末尾對)。

1.9 Python檔案操作

  • 檔案操作主要講解以下內容:
    • 1.檔案本身的操作(python內建)
    • 2.系統中檔案和資料夾的操作(os和shutil模組當中)
    • 3.系統路徑相關操作(os模組中的子模組 os.path)

(1) 檔案的基本操作

  • open() 開啟或者建立一個檔案
    格式:open('檔案路徑','開啟模式')
    返回值:檔案io物件

    開啟模式一共N種:

        w模式 寫模式write  檔案不存在時會建立檔案,如果檔案已存在則會清空檔案

        r模式  讀模式read  檔案不存在就報錯,存在則準備讀取檔案

        a模式 追加模式 append 檔案不存在則新建,檔案存在則在檔案末尾追加內容

        x模式 抑或模式 xor 檔案存在則報錯,檔案 不存在則新建檔案

        b模式 二進位制模式 binary 輔助模式不能單獨使用

        +模式 增強模式plus  也是輔助模式不能單獨使用
  • 以上模式可以互相組合:wrax不可以互相組合:
模式說明
r以只讀方式開啟檔案。檔案的指標將會放在檔案的開頭。這是預設模式。
w開啟一個檔案只用於寫入。如果該檔案已存在則將其覆蓋。如果該檔案不存在,建立新檔案。
a開啟一個檔案用於追加。如果該檔案已存在,檔案指標將會放在檔案的結尾。也就是說,新的內容將會被寫入到已有內容之後。如果該檔案不存在,建立新檔案進行寫入。
rb以二進位制格式開啟一個檔案用於只讀。檔案指標將會放在檔案的開頭。這是預設模式。
wb以二進位制格式開啟一個檔案只用於寫入。如果該檔案已存在則將其覆蓋。如果該檔案不存在,建立新檔案。
ab以二進位制格式開啟一個檔案用於追加。如果該檔案已存在,檔案指標將會放在檔案的結尾。也就是說,新的內容將會被寫入到已有內容之後。如果該檔案不存在,建立新檔案進行寫入。
r+開啟一個檔案用於讀寫。檔案指標將會放在檔案的開頭。
w+開啟一個檔案用於讀寫。如果該檔案已存在則將其覆蓋。如果該檔案不存在,建立新檔案。
a+開啟一個檔案用於讀寫。如果該檔案已存在,檔案指標將會放在檔案的結尾。檔案開啟時會是追加模式。如果該檔案不存在,建立新檔案用於讀寫。
rb+以二進位制格式開啟一個檔案用於讀寫。檔案指標將會放在檔案的開頭。
wb+以二進位制格式開啟一個檔案用於讀寫。如果該檔案已存在則將其覆蓋。如果該檔案不存在,建立新檔案。
ab+以二進位制格式開啟一個檔案用於追加。如果該檔案已存在,檔案指標將會放在檔案的結尾。如果該檔案不存在,建立新檔案用於讀寫。
  • close() 關閉檔案
格式:檔案io物件.close()
返回值:None
  • 示例如下:
    # 新建一個檔案,檔名為:test.txt
    f = open('test.txt', 'w')

    # 關閉這個檔案
    f.close()

讀寫函式:

  • read() 讀取檔案
    格式:檔案io物件.read()
    返回值:整個檔案的字元

    格式:檔案io物件.read(字元長度)
    返回值:指定長度的字元
f = open('test.txt', 'r')

content = f.read(5)

print(content)

print("-"*30)

content = f.read()

print(content)

f.close()
  • readline() 讀取一行檔案
    格式:檔案io物件.readline()
    返回值:一行內容的字串

    格式:檔案io物件.readline(字元長度)
    返回值:一行內容的字串

    注意:字元長度<當前行內內容,則讀取指定長度的字串,並且下次再讀取還是在
          這個一行中獲取沒有讀取的內容。字元長度>=當前行內容,直接讀取當前行
#coding=utf-8

f = open('test.txt', 'r')

content = f.readline()
print("1:%s"%content)

content = f.readline()
print("2:%s"%content)

f.close()
  • readlines() 將檔案中的內容讀取到序列當中。
    格式:檔案io物件.readlines()
    返回值:列表

    格式:檔案io物件.readlines(字元長度)
    返回值:列表

    注意:讀取的行數由字元長度決定,如果字元長度讀取了N行後,還有指定長度的字元
          沒有讀取,則直接讀取下一行進來
#coding=utf-8

f = open('test.txt', 'r')

content = f.readlines()

print(type(content))

i=1
for temp in content:
    print("%d:%s"%(i, temp))
    i+=1

f.close()
  • write() 寫入檔案
    格式:檔案io物件.write(字串)
    返回值:寫入字串的長度
  • writelines() 將序列寫入檔案中
    格式:檔案io物件.writelines(序列)
    返回值:None
  • truncate() 字串擷取操作
    格式:檔案io物件.truncate(位元組長度)
    返回值:擷取的位元組長度

(2) OS模組

  • OS – 作業系統的簡稱
  • os模組就是對作業系統進行操作
  • 使用該模組必須先匯入模組:
    import os

os模組中的函式:

序號函式名稱描述格式
1getcwd()獲取當前的工作目錄格式:os.getcwd() 返回值:路徑字串
2chdir()修改當前工作目錄格式:os.chdir() 返回值:None
3listdir()獲取指定資料夾中的 所有檔案和資料夾組成的列表格式:os.listdir(目錄路徑) 返回值:目錄中內容名稱的列表
4mkdir()建立一個目錄/資料夾格式:os.mkdir(目錄路徑) 返回值:None
5makedirs()遞迴建立資料夾格式:os.makedirs(路徑)
6rmdir()移除一個目錄(必須是空目錄)格式:os.rmdir(目錄路徑) 返回值:None
7removedirs()遞迴刪除資料夾格式:os.removedirs(目錄路徑) 返回值:None 注意最底層目錄必須為空
8rename()修改檔案和資料夾的名稱格式:os.rename(原始檔或資料夾,目標檔案或資料夾) 返回值:None
9stat()獲取檔案的相關 資訊格式:os.stat(檔案路徑) 返回值:包含檔案資訊的元組
10system()執行系統命令格式:os.system() 返回值:整型 慎用! 玩意來個rm -rf 你就爽了!
11getenv()獲取系統環境變數格式:os.getenv(獲取的環境變數名稱) 返回值:字串
12putenv()設定系統環境變數格式:os.putenv(‘環境變數名稱’,值) 返回值:無 注意:無法正常的getenv檢測到。
13exit()推出當前執行命令,直接關閉當前操作格式:exit() 返回值:無

當前os模組的值:

序號函式名稱描述
1curdiros.curdir 獲取當前路徑 都是.
2pardiros.pardir 獲取上層目錄路徑 都是…
3pathos.path os中的一個子模組,操作非常多
4nameos.name 當前系統的核心名稱 win->nt linux/unix->posix
5sepos.sep 獲取當前系統的路徑分割符號 window -> \ linux/unix -> /
6extsepos.extsep 獲取當前系統中檔名和字尾之間的分割符號,所有系統都是.
7linesepos.linesep 獲取當前系統的換行符號 window -> \r\n linux/unix -> \n

os.environ模組

  • os.environ 可以直接獲取所有環境變數的資訊組成的字典,如果希望更改環境變數,並且可以查詢得到,就需要對os.environ進行操作
  • 該模組的所有方法均是字典的方法,可以通過字典的os.environ的結果進行操作。
  • 注意:無論使用os.getenv,putenv 還是使用os.environ進行環境變數的操作,都是隻對當前指令碼,臨時設定而已,無法直接更新或者作業系統的環境變數設定。

os.path模組

  • os.path是os模組中的子模組,包含很多和路徑相關的操作
  • 函式部分:
序號函式名稱描述格式
1abspath()將一個相對路徑轉化為絕對路徑格式:os.path.abspath(相對路徑) 返回值:絕對路徑字串
2basename()獲取路徑中的資料夾或者檔名稱 (只要路徑的最後一部分)格式:os.path.basename(路徑) 返回值:路徑的最後一部分(可能是檔名也可能是資料夾名)
3dirname()獲取路徑中的路徑部分(出去最後一部分)格式:os.path.dirname(路徑) 返回值:路徑中除了最後一部分的內容字串
4join()將2個路徑合成一個路徑格式:os.path.join(路徑1,路徑2) 返回值:合併之後的路徑
5split()將一個路徑切割成資料夾和檔名部分格式:os.path.split(路徑) 返回值:元組
6splitext()將一個檔名切成名字和字尾兩個部分格式:os.path.splitext(檔名稱) 返回值:元組 (名稱,字尾)
7getsize()獲取一個檔案的大小格式:os.path.getsize(路徑) 返回值:整數
8isfile()檢測一個路徑是否是一個檔案格式:os.path.isfile(路徑) 返回值:布林值
9isdir()檢測一個路徑是否是一個資料夾格式:os.path.isdir(路徑) 返回值:布林值
10getctime()獲取檔案的建立時間! get create time格式:os.path.getctime(檔案路徑) 返回值:時間戳浮點數
11getmtime()獲取檔案的修改時間! get modify time格式:os.path.getmtime(檔案路徑) 返回值:時間戳浮點數
12getatime()獲取檔案的訪問時間! get active time格式:os.path.getatime(檔案路徑) 返回值:時間戳浮點數
13exists()檢測指定的路徑是否存在格式:os.path.exists(路徑) 返回值:布林值
14isabs()檢測一個路徑是否是絕對路徑格式:os.path.isabs(路徑) 返回值:布林值
15islink()檢測一個路徑是否是連結格式:os.path.islink(路徑) 返回值:布林值
16samefile()檢測2個路徑是否指向同一個檔案格式:os.path.samefile(路徑1,路徑2) 返回值:布林值

1.10 綜合案例實戰

使用python學習內容實現一個線上學員資訊管理操作

  • 資料臨時存放在變數列表中
  • 實現學生資訊的新增,刪除和查詢操作。
初識介面:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-MTNUq2tu-1603700619111)(https://edu.csdn.net/notebook/python/images/week01/2018-01-22_070330.png)]

新增學員資訊

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-BGasgXuW-1603700619112)(https://edu.csdn.net/notebook/python/images/week01/2018-01-22_070431.png)]

瀏覽學員資訊

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-DQgAdgK7-1603700619113)(https://edu.csdn.net/notebook/python/images/week01/2018-01-22_070443.png)]

刪除學員資訊

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-KPaDpTwF-1603700619114)(https://edu.csdn.net/notebook/python/images/week01/2018-01-22_070520.png)]

退出操作

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-rVzY6IGP-1603700619115)(https://edu.csdn.net/notebook/python/images/week01/2018-01-22_070540.png)]

參考程式程式碼如下:

# 學員資訊線上管理

# 定義一個用於存放學員資訊的列表變數
stulist=[
    {'name':'zhangsan','age':20,'classid':'python02'},
    {'name':'lisi','age':22,'classid':'python03'},
    {'name':'wangwu','age':25,'classid':'python04'}]

#定義一個學生資訊的輸出函式
def showStu(stulist):
    '''
    學生資訊的輸出函式
    '''
    if len(stulist)==0:
        print("========== 沒有學員資訊可以輸出!=============")
        return
    print("|{0:<5}| {1:<10}| {2:<5}| {3:<10}|".format("sid","name","age","classid"))
    print("-"*40)
    for i in range(len(stulist)):
        print("|{0:<5}| {1:<10}| {2:<5}| {3:<10}|".format(i+1,stulist[i]['name'],stulist[i]['age'],stulist[i]['classid']))


while True:
    # 輸出初始介面
    print("="*12,"學員管理系統","="*14)
    print("{0:1} {1:13} {2:15}".format(" ","1. 檢視學員資訊","2. 新增學員資訊"))
    print("{0:1} {1:13} {2:15}".format(" ","3. 刪除學員資訊","4. 退出系統"))
    print("="*40)
    key = input("請輸入對應的選擇:")
    # 根據鍵盤值,判斷並執行對應的操作
    if key == "1":
        print("="*12,"學員資訊瀏覽","="*14)
        showStu(stulist)
        input("按Enter鍵繼續:")
    elif key == "2":
        print("="*12,"學員資訊新增","="*14)
        stu={}
        stu['name']=input("請輸入要新增的姓名:")
        stu['age']=input("請輸入要新增的年齡:")
        stu['classid']=input("請輸入要新增的班級號:")
        stulist.append(stu)
        showStu(stulist)
        input("按Enter鍵繼續:")
    elif key == "3":
        print("="*12,"學員資訊刪除","="*14)
        showStu(stulist)
        sid = input("請輸入你要刪除的資訊id號:")
        del stulist[int(sid)-1]
        showStu(stulist)
        input("按Enter鍵繼續:")
    elif key == "4":
        print("="*12,"再見","="*14)
        break
    else:
        print("======== 無效的鍵盤輸入! ==========")

二、Python基礎進階

1.11 Python物件導向程式設計

  • Python從設計之初就已經是一門物件導向的語言,正因為如此,在Python中建立一個類和物件是很容易的.

物件導向技術簡介

  • 類(Class): 用來描述具有相同的屬性和方法的物件的集合。它定義了該集合中每個物件所共有的屬性和方法。物件是類的例項。
  • 類變數:類變數在整個例項化的物件中是公用的。類變數定義在類中且在函式體之外。類變數通常不作為例項變數使用。
  • 資料成員:類變數或者例項變數用於處理類及其例項物件的相關的資料。
  • 方法重寫:如果從父類繼承的方法不能滿足子類的需求,可以對其進行改寫,這個過程叫方法的覆蓋(override),也稱為方法的重寫。
  • 例項變數:定義在方法中的變數,只作用於當前例項的類。
  • 繼承:即一個派生類(derived class)繼承基類(base class)的欄位和方法。繼承也允許把一個派生類的物件作為一個基類物件對待。例如,有這樣一個設計:一個Dog型別的物件派生自Animal類,這是模擬"是一個(is-a)"關係(例圖,Dog是一個Animal)。
  • 例項化:建立一個類的例項,類的具體物件。
  • 方法:類中定義的函式。
  • 物件:通過類定義的資料結構例項。物件包括兩個資料成員(類變數和例項變數)和方法。

1.11.2 類和物件

3

class ClassName:
    <statement-1>
    .
    .
    .
    <statement-N>
  • 例項:
#!/usr/bin/python3

# 類的定義
class MyClass:
    i = 12345
    def f(self):
        return 'hello world'

# 例項化類
x = MyClass()

# 訪問類的屬性和方法
print("MyClass 類的屬性 i 為:", x.i)
print("MyClass 類的方法 f 輸出為:", x.f())

# 結果:
# MyClass 類的屬性 i 為: 12345
# MyClass 類的方法 f 輸出為: hello world

1.11.3 建構函式

  • 很多類都傾向於將物件建立為有初始狀態的。因此類可能會定義一個名為 init() 的特殊方法(構造方法),像下面這樣:
def __init__(self):
    self.data = []
  • 類定義了 init() 方法的話,類的例項化操作會自動呼叫 init() 方法。所以在下例中,可以這樣建立一個新的例項:
x = MyClass()
  • 當然, init() 方法可以有引數,引數通過 init() 傳遞到類的例項化操作上。例如:
#!/usr/bin/python3

class Complex:
    def __init__(self, realpart, imagpart):
        self.r = realpart
        self.i = imagpart
x = Complex(3.0, -4.5)
print(x.r, x.i)   # 輸出結果:3.0 -4.5

self代表類的例項,而非類

  • 類的方法與普通的函式只有一個特別的區別——它們必須有一個額外的第一個引數名稱, 按照慣例它的名稱是 self。
class Test:
    def prt(self):
        print(self)
        print(self.__class__)

t = Test()
t.prt()
  • 以上例項執行結果為:
<__main__.Test instance at 0x100771878>
__main__.Test
  • 從執行結果可以很明顯的看出,self 代表的是類的例項,代表當前物件的地址,而 self.class 則指向類。
  • self 不是 python 關鍵字,我們可以換成其他變數名

1.11.4 類的屬性和方法

類的方法:
  • 在類地內部,使用 def 關鍵字來定義一個方法,與一般函式定義不同,類方法必須包含引數 self, 且為第一個引數,self 代表的是類的例項。
#!/usr/bin/python3

#類定義
class people:
    #定義基本屬性
    name = ''
    age = 0
    #定義私有屬性,私有屬性在類外部無法直接進行訪問
    __weight = 0
    #定義構造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s 說: 我 %d 歲。" %(self.name,self.age))

# 例項化類
p = people('runoob',10,30)
p.speak()
  • 執行以上程式輸出結果為:
runoob 說: 我 10 歲。

類屬性與方法:

  • 類的私有屬性
    
    • **private_attrs:兩個下劃線開頭,宣告該屬性為私有,不能在類地外部被使用或直接訪問。在類內部的方法中使用時 self.**private_attrs。
  • 類的方法
    
    • 在類地內部,使用 def 關鍵字來定義一個方法,與一般函式定義不同,類方法必須包含引數 self,且為第一個引數,self 代表的是類的例項。
    • self 的名字並不是規定死的,也可以使用 this,但是最好還是按照約定是用 self。
  • 類的私有方法
    
    • **private_method:兩個下劃線開頭,宣告該方法為私有方法,只能在類的內部呼叫 ,不能在類地外部呼叫。self.**private_methods。

1.11.5 繼承與過載

  • Python 同樣支援類的繼承,如果一種語言不支援繼承,類就沒有什麼意義。派生類的定義如下所示:
class DerivedClassName(BaseClassName1):
    <statement-1>
    .
    .
    .
    <statement-N>
#!/usr/bin/python3

#類定義
class people:
    #定義基本屬性
    name = ''
    age = 0
    #定義私有屬性,私有屬性在類外部無法直接進行訪問
    __weight = 0
    #定義構造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s 說: 我 %d 歲。" %(self.name,self.age))

#單繼承示例
class student(people):
    grade = ''
    def __init__(self,n,a,w,g):
        #呼叫父類的構函
        people.__init__(self,n,a,w)
        self.grade = g
    #覆寫父類的方法
    def speak(self):
        print("%s 說: 我 %d 歲了,我在讀 %d 年級"%(self.name,self.age,self.grade))



s = student('ken',10,60,3)
s.speak()


# 執行以上程式輸出結果為:
# ken 說: 我 10 歲了,我在讀 3 年級
多繼承:
  • Python同樣有限的支援多繼承形式。多繼承的類定義形如下例:
class DerivedClassName(Base1, Base2, Base3):
    <statement-1>
    .
    .
    .
    <statement-N>
  • 需要注意圓括號中父類的順序,若是父類中有相同的方法名,而在子類使用時未指定,python從左至右搜尋 即方法在子類中未找到時,從左到右查詢父類中是否包含方法。
#!/usr/bin/python3

#類定義
class people:
    #定義基本屬性
    name = ''
    age = 0
    #定義私有屬性,私有屬性在類外部無法直接進行訪問
    __weight = 0
    #定義構造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s 說: 我 %d 歲。" %(self.name,self.age))

#單繼承示例
class student(people):
    grade = ''
    def __init__(self,n,a,w,g):
        #呼叫父類的構函
        people.__init__(self,n,a,w)
        self.grade = g
    #覆寫父類的方法
    def speak(self):
        print("%s 說: 我 %d 歲了,我在讀 %d 年級"%(self.name,self.age,self.grade))

#另一個類,多重繼承之前的準備
class speaker():
    topic = ''
    name = ''
    def __init__(self,n,t):
        self.name = n
        self.topic = t
    def speak(self):
        print("我叫 %s,我是一個演說家,我演講的主題是 %s"%(self.name,self.topic))

#多重繼承
class sample(speaker,student):
    a =''
    def __init__(self,n,a,w,g,t):
        student.__init__(self,n,a,w,g)
        speaker.__init__(self,n,t)

test = sample("Tim",25,80,4,"Python")
test.speak()   #方法名同,預設呼叫的是在括號中排前地父類的方法


# 執行以上程式輸出結果為:
# 我叫 Tim,我是一個演說家,我演講的主題是 Python
方法重寫:
  • 如果你的父類方法的功能不能滿足你的需求,你可以在子類重寫你父類的方法,例項如下:
#!/usr/bin/python3

class Parent:        # 定義父類
   def myMethod(self):
      print ('呼叫父類方法')

class Child(Parent): # 定義子類
   def myMethod(self):
      print ('呼叫子類方法')

c = Child()          # 子類例項
c.myMethod()         # 子類呼叫重寫方法

# 執行以上程式輸出結果為:
# 呼叫子類方法

1.11.6 其他

  • 類的專有方法:
    • __init__: 建構函式,在生成物件時呼叫
    • __del__: 解構函式,釋放物件時使用
    • __repr__: 列印,轉換
    • __setitem__ : 按照索引賦值
    • __getitem__: 按照索引獲取值
    • __len__: 獲得長度
    • __cmp__: 比較運算
    • __call__: 函式呼叫
    • __add__: 加運算
    • __sub__: 減運算
    • __mul__: 乘運算
    • __div__: 除運算
    • __mod__: 求餘運算
    • __pow__: 乘方
  • 運算子過載
  • Python同樣支援運算子過載,我們可以對類的專有方法進行過載,例項如下:
#!/usr/bin/python3

class Vector:
   def __init__(self, a, b):
      self.a = a
      self.b = b

   def __str__(self):
      return 'Vector (%d, %d)' % (self.a, self.b)

   def __add__(self,other):
      return Vector(self.a + other.a, self.b + other.b)

v1 = Vector(2,10)
v2 = Vector(5,-2)
print (v1 + v2)

# 以上程式碼執行結果如下所示:
# Vector(7,8)

1.12 Python中的異常處理

1.12.1 異常介紹

  • 即便Python程式的語法是正確的,在執行它的時候,也有可能發生錯誤。執行期檢測到的錯誤被稱為異常。
  • 大多數的異常都不會被程式處理,都以錯誤資訊的形式展現在這裡:
>>> 10 * (1/0)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ZeroDivisionError: division by zero
>>> 4 + spam*3
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
NameError: name 'spam' is not defined
>>> '2' + 2
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: Can't convert 'int' object to str implicitly
  • 異常以不同的型別出現,這些型別都作為資訊的一部分列印出來: 例子中的型別有 ZeroDivisionError,NameError 和 TypeError。
  • Python的一些內建異常:
Exception       常規錯誤的基類
AttributeError  物件沒有這個屬性
IOError         輸入/輸出操作失敗
IndexError      序列中沒有此索引(index)
KeyError        對映中沒有這個鍵
NameError       未宣告/初始化物件 (沒有屬性)
SyntaxError     Python 語法錯誤
TypeError       對型別無效的操作
ValueError      傳入無效的引數
ZeroDivisionError   除(或取模)零 (所有資料型別)
  • 更多可以參考:http://blog.csdn.net/gavin_john/article/details/50738323
附加:Python—內建異常體系結構

Python異常體系結構如下圖:

img

常見的異常如下表所示:

異常名稱描述
BaseException所有異常的基類
SystemExit直譯器請求退出
KeyboardInterrupt使用者中斷執行(通常是輸入^C)
Exception常規錯誤的基類
StopIteration迭代器沒有更多的值
GeneratorExit生成器(generator)發生異常來通知退出
StandardError所有的內建標準異常的基類
ArithmeticError所有數值計算錯誤的基類
FloatingPointError浮點計算錯誤
OverflowError數值運算超出最大限制
ZeroDivisionError除(或取模)零 (所有資料型別)
AssertionError斷言語句失敗
AttributeError物件沒有這個屬性
EOFError沒有內建輸入,到達EOF 標記
EnvironmentError作業系統錯誤的基類
IOError輸入/輸出操作失敗
OSError作業系統錯誤
WindowsError系統呼叫失敗
ImportError匯入模組/物件失敗
LookupError無效資料查詢的基類
IndexError序列中沒有此索引(index)
KeyError對映中沒有這個鍵
MemoryError記憶體溢位錯誤(對於Python 直譯器不是致命的)
NameError未宣告/初始化物件 (沒有屬性)
UnboundLocalError訪問未初始化的本地變數
ReferenceError弱引用(Weak reference)試圖訪問已經垃圾回收了的物件
RuntimeError一般的執行時錯誤
NotImplementedError尚未實現的方法
SyntaxErrorPython 語法錯誤
IndentationError縮排錯誤
TabErrorTab 和空格混用
SystemError一般的直譯器系統錯誤
TypeError對型別無效的操作
ValueError傳入無效的引數
UnicodeErrorUnicode 相關的錯誤
UnicodeDecodeErrorUnicode 解碼時的錯誤
UnicodeEncodeErrorUnicode 編碼時錯誤
UnicodeTranslateErrorUnicode 轉換時錯誤
Warning警告的基類
DeprecationWarning關於被棄用的特徵的警告
FutureWarning關於構造將來語義會有改變的警告
OverflowWarning舊的關於自動提升為長整型(long)的警告
PendingDeprecationWarning關於特性將會被廢棄的警告
RuntimeWarning可疑的執行時行為(runtime behavior)的警告
SyntaxWarning可疑的語法的警告
UserWarning使用者程式碼生成的警告
# 注意:
BaseException是異常的頂級類。但是這個類不能當作是由使用者定義的類直接繼承的,而是要繼承Exception。Exception類是與應用相關的異常的頂層根超類,除了系統退出事件類之外(SystemExit、KeyboardInterrupt和GeneratorExit),幾乎所有的使用者定義的類都應該繼承自這個類,而不是BaseException

1.12.2 異常處理

  • 沒有異常處理的:特點是出現異常會終止程式執行。
print("start.....")
x = int(input("Please enter a number: "))
print("number:",x)
print("ok....")
print("end.....")
  • 使用了有異常處理的程式碼,程式會執行到最後
print("start.....")
try:
    x = int(input("Please enter a number: "))
    print("number:",x)
    print("ok....")
except ValueError:
    print("Oops!  That was no valid number.  Try again")
print("end.....")
  • try語句按照如下方式工作;
    • 首先,執行try子句(在關鍵字try和關鍵字except之間的語句)
    • 如果沒有異常發生,忽略except子句,try子句執行後結束。
    • 如果在執行try子句的過程中發生了異常,那麼try子句餘下的部分將被忽略。如果異常的型別和 except 之後的名稱相符,那麼對應的except子句將被執行。最後執行 try 語句之後的程式碼。
    • 如果一個異常沒有與任何的except匹配,那麼這個異常將會傳遞給上層的try中。
  • 一個 try 語句可能包含多個except子句,分別來處理不同的特定的異常。最多隻有一個分支會被執行。
  • 處理程式將只針對對應的try子句中的異常進行處理,而不是其他的 try 的處理程式中的異常。
  • 一個except子句可以同時處理多個異常,這些異常將被放在一個括號裡成為一個元組,例如:
    except (RuntimeError, TypeError, NameError):
        pass
  • 最後一個except子句可以忽略異常的名稱,它將被當作萬用字元使用。你可以使用這種方法列印一個錯誤資訊,然後再次把異常丟擲。
import sys

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except OSError as err:
    print("OS error: {0}".format(err))
except ValueError:
    print("Could not convert data to an integer.")
except:
    print("Unexpected error:", sys.exc_info()[0])
    raise
異常處理例項
  • 一個 try 語句可能包含多個except子句,分別來處理不同的特定的異常。最多隻有一個分支會被執行
  • 最後一個except子句可以忽略異常的名稱,它將被當作萬用字元使用
print("start.....")
try:
    x = int(input("Please enter a number: "))
    print("number:",x)
    print(100/x)
    print("ok....")
except ValueError:
    print("非純數字錯誤!")
except ZeroDivisionError:
    print("不可以為零錯誤!")
except:
    print("可選的未知錯誤!")
print("end.....")
  • 一個except子句可以同時處理多個異常,這些異常將被放在一個括號裡成為一個元組
print("start.....")
try:
    x = int(input("Please enter a number: "))
    print("number:",x)
    print(100/x)
    print("ok....")
except (ValueError,ZeroDivisionError):
    print("非純數字或不可以為零錯誤!")
except:
    print("可選的未知錯誤!")
    raise   #重新丟擲這個異常
print("end.....")

1.12.3 丟擲異常(自行丟擲異常)

  • Python 使用 raise 語句丟擲一個指定的異常。例如:
>>> raise NameError('HiThere')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
NameError: HiThere
  • raise 唯一的一個引數指定了要被丟擲的異常。它必須是一個異常的例項或者是異常的類(也就是 Exception 的子類)。
  • 如果你只想知道這是否丟擲了一個異常,並不想去處理它,那麼一個簡單的 raise 語句就可以再次把它丟擲。
>>> try:
        raise NameError('HiThere')
    except NameError:
        print('An exception flew by!')
        raise

An exception flew by!
Traceback (most recent call last):
  File "<stdin>", line 2, in ?
NameError: HiThere

1.13 魔術方法、屬性和迭代器

1.13.1 魔術方法:

  • 在Python中的物件導向中有很多魔術方法如:
  __init__: 建構函式,在生成物件時呼叫
  __del__: 解構函式,釋放物件時使用
  __str__: 使用print(物件)或者str(物件)的時候觸發
  __repr__: 在使用repr(物件)的時候觸發
  __setitem__ : 按照索引賦值:每當屬性被賦值的時候都會呼叫該方法:self.__dict__[name] = value
  __getitem__: 按照索引獲取值:當訪問不存在的屬性時會呼叫該方法
  _delitem__(self,name): 當刪除屬性時呼叫該方法
  __len__: 獲得長度
  __cmp__: 比較運算
  __call__: 函式呼叫
  __add__: 加運算
  __sub__: 減運算
  __mul__: 乘運算
  __div__: 除運算
  __mod__: 求餘運算
  __pow__: 乘方
  ...
  • 注意: __setitem__: 每當屬性被賦值的時候都會呼叫該方法,因此不能再該方法內賦值 self.name = value 會死迴圈
  • __str__函式用於處理列印例項本身的時候的輸出內容。如果沒有覆寫該函式,則預設輸出一個物件名稱和記憶體地址。
class Stu:
  name= '張三'
  age = 20
  def __str__(self):
    return "姓名:%s; 年齡:%d"%(self.name,self.age)

s = Stu()
print(s)
  • 析構魔術方法,當物件從記憶體被釋放前呼叫的方法,目的是做一些釋放銷燬工作。
class Demo:
  def __init__(self,x):
    self.x = x;
    print("create demo...",self.x)
  def __del__(self):
    print("del demo....",self.x)

d1 = Demo(1)
d2 = Demo(2)
d3 = Demo(3)
del d3
  • __add__: 加運算
class Vector:
   def __init__(self, a, b):
      self.a = a
      self.b = b

   def __str__(self):
      return 'Vector (%d, %d)' % (self.a, self.b)

   def __add__(self,other):
      return Vector(self.a + other.a, self.b + other.b)

v1 = Vector(2,10)
v2 = Vector(5,-2)
print (v1 + v2)

# 以上程式碼執行結果如下所示:
# Vector(7,8)

1.13.2 屬性和方法

property() 函式的作用是在新式類中返回屬性值
* ```class property([fget[, fset[, fdel[, doc]]]])```
* fget -- 獲取屬性值的函式
* fset -- 設定屬性值的函式(可選)
* fdel -- 刪除屬性值函式(可選)
* doc -- 屬性描述資訊(可選)
# 定義一個矩形類,假象有一個size特性訪問器方法
class Rectangle:
  def __init__(self):
    self.width = 0
    self.height = 0
  def setSize(self,size):
    self.width,self.height=size
  def getSize(self):
    return self.width,self.height
#測試   
rt = Rectangle()
#rt.width=100
#rt.height=50
rt.setSize((200,100)) #賦值
print(rt.getSize())  #(200,100)
  • 對應上面的例項,
class Rectangle:
  def __init__(self):
    self.width = 0
    self.height = 0
  def setSize(self,size):
    self.width,self.height=size
  def getSize(self):
    return self.width,self.height

  size = property(getSize,setSize,fdel)

rt = Rectangle()
#rt.width=100
#rt.height=50
rt.setSize((200,100))
print(rt.getSize())


rt.size = 10,5
print(rt.size)
靜態方法和類成員方法(區別是有無帶引數)
  • 使用staticmethod()和classmethod()函式 或使用@staticmethod和@classmethod裝飾器
class MyClass1:
  def smeth():
    print('這是一個靜態方法')
  smeth = staticmethod(smeth)

  def cmeth(cls):
    print("這是一個類成員方法",cls)
  cmeth = classmethod(cmeth)

MyClass1.smeth()
MyClass1.cmeth()
#或使用使用@staticmethod和@classmethod裝飾器
class MyClass2:
  @staticmethod
  def smeth():
    print('這是一個靜態方法')

  @classmethod
  def cmeth(cls):
    print("這是一個類成員方法",cls)

MyClass2.smeth()
MyClass2.cmeth()
  • 使用hasattr()函式判讀物件中是否存在指定的非私有屬性和方法:
class B:
  name="zhangsan"
  __age=20
  def bb(self):
    print("bbbbb")
  def __cc(self):
    print("cccc")

b = B()
print(hasattr(b,"name"))  #True
print(hasattr(b,"__age")) #False
print(hasattr(b,"sex"))   #False
print(hasattr(b,"bb"))    #True
print(hasattr(b,"__cc"))  #False
print()

1.13.3 迭代器:

  • 指定資料建立迭代器(使用iter()和next() )
x = [1, 2, 3] #定義一個列表:<class 'list'>
y = iter(x)   #建立一個可迭代物件:<class 'list_iterator'>
#print(next(y)) # 1
#print(next(y)) # 2
#print(next(y)) # 3
#print(next(y)) # 迭代結束會後返回異常StopIteration錯誤
for i in y:
  print(i,end=" ")
print()

# 1  2  3
  • 迭代物件:定義魔術方法:__next__()__iter__()
class A:
  def __init__(self):
    self.x=0
  def __next__(self):
    self.x += 1
    if self.x>10:
      raise StopIteration
    return self.x
  def __iter__(self):
    return self

a = A()
print(list(a))
#for i in a:
# print(i)
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

1.14 Python模組實戰

1.14.1 什麼是Python模組

  • Python 模組(Module),是一個 Python 檔案,以 .py 結尾,包含了 Python 物件定義和Python語句。
  • 模組讓你能夠有邏輯地組織你的 Python 程式碼段。
  • 把相關的程式碼分配到一個模組裡能讓你的程式碼更好用,更易懂。
  • 模組能定義函式,類和變數,模組裡也能包含可執行的程式碼。

1.14.2 Python模組的匯入

(1) import 語句

  • 想使用 Python 原始檔,只需在另一個原始檔裡執行 import 語句,語法如下:
import module1[, module2[,... moduleN]
import random

random.choice([0,1,2,3,4,5])  #隨機從列表中獲取一個

random.randrange(1,10)  #1~9隨機一個
import time

# 格式化成2016-03-20 11:45:39形式
print (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

(2) from…import 語句

  • Python的from語句讓你從模組中匯入一個指定的部分到當前名稱空間中,語法如下:
from modname import name1[, name2[, ... nameN]]
from time import strftime,localtime

# 格式化成2016-03-20 11:45:39形式
print (strftime("%Y-%m-%d %H:%M:%S", localtime()))

1.14.3 第三方模組的安裝

  • 使用pip命令安裝
    • pip install 模組名
    • pip uninstall 模組名
    • pip freeze --檢視都安裝了哪些模組名
  • whl下載安裝的方式
    • 網址: https://www.lfd.uci.edu/~gohlke/pythonlibs/ 下載
    • 安裝:pip install 檔案包名
  • 直接複製的方式
  • anaconda

1.14.4 自定義Python模組

  • 在匯入一個包的時候,Python 會根據 sys.path 中的目錄來尋找這個包中包含的子目錄。
  • 目錄只有包含一個叫做__init__.py 的檔案才會被認作是一個包,主要是為了避免一些濫俗的名字(比如叫做 string)不小心的影響搜尋路徑中的有效模組。
  • 最簡單的情況,放一個空的 :file:__init__.py就可以了。當然這個檔案中也可以包含一些初始化程式碼或者為(將在後面介紹的)__all__變數賦值。

1.15 MySQL資料庫基礎

1.15.1 MySQL簡介

  • Mysql是最流行的RDBMS(Relational Database Management System:關聯式資料庫管理系統),特別是在WEB應用方面。
  • 資料庫(Database)是按照資料結構來組織、儲存和管理資料的倉庫,
  • 每個資料庫都有一個或多個不同的API用於建立,訪問,管理,搜尋和複製所儲存的資料。
  • 所謂的關係型資料庫,是建立在關係模型基礎上的資料庫,藉助於集合代數等數學概念和方法來處理資料庫中的資料。
  • RDBMS即關聯式資料庫管理系統(Relational Database Management System)的特點:
    • 1.資料以表格的形式出現
    • 2.每行為各種記錄名稱
    • 3.每列為記錄名稱所對應的資料域
    • 4.許多的行和列組成一張表單
    • 5.若干的表單組成database
  • 在我們開始學習MySQL 資料庫前,讓我們先了解下RDBMS的一些術語:
資料庫: 資料庫是一些關聯表的集合。.
資料表: 表是資料的矩陣。在一個資料庫中的表看起來像一個簡單的電子表格。
列: 一列(資料元素) 包含了相同的資料, 例如郵政編碼的資料。
行:一行(=元組,或記錄)是一組相關的資料,例如一條使用者訂閱的資料。
冗餘:儲存兩倍資料,冗餘降低了效能,但提高了資料的安全性。
主鍵:主鍵是唯一的。一個資料表中只能包含一個主鍵。你可以使用主鍵來查詢資料。
外來鍵:外來鍵用於關聯兩個表。
複合鍵:複合鍵(組合鍵)將多個列作為一個索引鍵,一般用於複合索引。
索引:使用索引可快速訪問資料庫表中的特定資訊。索引是對資料庫表中一列或多列的值進行排序的一種結構。類似於書籍的目錄。
參照完整性: 參照的完整性要求關係中不允許引用不存在的實體。與實體完整性是關係模型必須滿足的完整性約束條件,目的是保證資料的一致性。
SQL:
  • SQL: 結構化查詢語言(Structured Query Language)簡稱SQL,是最重要的關聯式資料庫操作語言.
  • 有上百種資料庫產品都支援SQL,如:MySQL、DB2、ORACLE、INGRES、SYBASE、SQLSERVER…
  • 結構化查詢語言包含6個部分:
1. 資料查詢語言(DQL:Data Query Language):SELECT
2. 資料操作語言(DML:Data Manipulation Language):INSERT,UPDATE和DELETE
3. 事務處理語言(TPL):BEGIN TRANSACTION,COMMIT和ROLLBACK
4. 資料控制語言(DCL):GRANT(授權)或REVOKE(回收許可權)
5. 資料定義語言(DDL):CREATE、ALTER和DROP
6. 指標控制語言(CCL):DECLARE CURSOR,FETCH INTO和UPDATE WHERE CURRENT用於對一個或多個表單獨行的操作
  • 在本節中,會讓大家快速掌握Mysql的基本知識,並輕鬆使用Mysql資料庫。
mysql資料庫的安裝:
  • 網址:https://www.mysql.com/downloads/ 下載,但是已經是商業版了
  • 可下載 MariaDB 開源的 https://downloads.mariadb.org
  • 建議Window上可以安裝一個整合環境如:XAMPP:https://www.apachefriends.org/zh_cn/download.html
  • Ubuntu系統安裝:sudo apt-get install mysql-server mysql-client
  • 服務的啟動和停止
  • 配置檔案:windows下是:my.ini Linux下:mysqld.conf
連線資料庫:
mysql -h 主機名 -u 使用者名稱  -p密碼  庫名

C:\>mysql  --採用匿名賬號和密碼登陸本機服務
C:\>mysql -h localhost -u root -proot   --採用root賬號和root密碼登陸本機服務
C:\>mysql -u root -p   --推薦方式預設登陸本機
  Enter password: ****

C:\>mysql -u root -p mydb  --直接進入mydb資料庫的方式登陸

SQL語句中的快捷鍵
  \G 格式化輸出(文字式,豎立顯示)
  \s 檢視伺服器端資訊
  \c 結束命令輸入操作
  \q 退出當前sql命令列模式
  \h 檢視幫助

1.15.2. SQL的基本操作

資料庫操作:
mysql> show databases;                              --檢視當前使用者下的所有資料庫
mysql> create database [if not exists] 資料庫名;  --建立資料庫
mysql> use test;                                 --選擇進入test資料庫
mysql> show create database 資料庫名\G               --檢視建資料庫語句 
mysql> select database();                           --檢視當前所在的資料庫位置 
mysql> drop database [if exists] 資料庫名;           --刪除一個資料庫
資料表操作:
mysql> show tables;             --檢視當前庫下的所有表格
mysql> desc tb1;                  --檢視tb1的表結構。
mysql> show create table 表名\G  --檢視錶的建表語句。
mysql> create table demo(        --建立demo表格
    -> name varchar(16) not null,
    -> age int,
    -> sex enum('w','m') not null default 'm');
Query OK, 0 rows affected (0.05 sec)

mysql> show columns from demo;  --檢視錶結構
mysql> desc demo;                  --檢視錶結構
+-------+---------------+------+-----+---------+-------+
| Field | Type          | Null | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| name  | varchar(16)   | NO   |     | NULL    |       |
| age   | int(11)       | YES  |     | NULL    |       |
| sex   | enum('w','m') | NO   |     | m       |       |
+-------+---------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql>drop table if exists mytab;  -- 嘗試刪除mytab表格
資料操作:
--新增一條資料
mysql> insert into demo(name,age,sex) values('zhangsan',20,'w');
Query OK, 1 row affected (0.00 sec)

--不指定欄位名來新增資料
mysql> insert into demo values('lisi',22,'m'); 
Query OK, 1 row affected (0.00 sec)

--指定部分欄位名來新增資料
mysql> insert into demo(name,age) values('wangwu',23); 
Query OK, 1 row affected (0.00 sec)

--批量新增資料
mysql> insert into demo(name,age,sex) values('aaa',21,'w'),("bbb",22,'m');
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from demo; --查詢資料

mysql> update demo set age=24 where name='aaa';  --修改
Query OK, 1 row affected (0.02 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> delete from demo where name='bbb';  --刪除
Query OK, 1 row affected (0.00 sec)

1.15.3 MySQL資料結構型別及操作:

MySQL的資料型別分為三個類:數值型別、字串型別、日期型別 。 還有一個特殊的值:NULL。
1 數值型別:
    *tinyint(1位元組) 0~255  -128~127
    smallint(2位元組)
    mediumint(3位元組)
    *int(4位元組)
    bigint(8位元組)
    *float(4位元組)   float(6,2)
    *double(8位元組)  
    decimal(自定義)字串形數值

2 字串型別
    普通字串
    *char    定長字串        char(8)  
    *varchar 可變字串 varchar(8)

    二進位制型別
    tinyblob
    blob
    mediumblob
    longblob

    文字型別
    tinytext
    *text      常用於<textarea></textarea>
    mediumtext
    longtext

    *enum列舉
    set集合

3 時間和日期型別:
    date  年月日
    time  時分秒
    *datetime 年月日時分秒
    timestamp 時間戳
    year 年

4 NULL值
    NULL意味著“沒有值”或“未知值”
    可以測試某個值是否為NULL
    不能對NULL值進行算術計算
    對NULL值進行算術運算,其結果還是NULL
    0或NULL都意味著假,其餘值都意味著真
MySQL的運算子:
算術運算子:+ - * / % 
比較運算子:= > < >= <= <> != 
資料庫特有的比較:in,not in, is null,is not null,like, between and 
邏輯運算子:and or not
表的欄位約束:
unsigned 無符號(正數)
zerofill 前導零填充
auto_increment 自增
default    預設值
not null  非空
PRIMARY KEY 主鍵 (非null並不重複)
unique 唯一性   (可以為null但不重複)
index 常規索引
建表語句格式:
 create table 表名(
   欄位名 型別 [欄位約束],
   欄位名 型別 [欄位約束],
   欄位名 型別 [欄位約束],
   ...
  );
mysql> create table stu(
    -> id int unsigned not null auto_increment primary key,
    -> name varchar(8) not null unique,
    -> age tinyint unsigned,
    -> sex enum('m','w') not null default 'm',
    -> classid char(6)
    -> );
Query OK, 0 rows affected (0.05 sec)


mysql> desc stu;
+---------+---------------------+------+-----+---------+----------------+
| Field   | Type                | Null | Key | Default | Extra          |
+---------+---------------------+------+-----+---------+----------------+
| id      | int(10) unsigned    | NO   | PRI | NULL    | auto_increment |
| name    | varchar(8)          | NO   | UNI | NULL    |                |
| age     | tinyint(3) unsigned | YES  |     | NULL    |                |
| sex     | enum('m','w')       | NO   |     | m       |                |
| classid | char(6)             | YES  |     | NULL    |                |
+---------+---------------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

mysql> show create table stu\G  --檢視建表的語句
*************************** 1. row ***************************
       Table: stu
Create Table: CREATE TABLE `stu` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `name` varchar(8) NOT NULL,
  `age` tinyint(3) unsigned default NULL,
  `sex` enum('m','w') NOT NULL default 'm',
  `classid` char(6) default NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `name` (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
修改表結構:
格式: alter table 表名 action(更改選項);
 更改選項:
    1. 新增欄位:alter table 表名 add 欄位名資訊
        例如:
            -- 在user表的最後追加一個num欄位 設定為int not null
            mysql> alter table user add num int not null;

            -- 在user表的email欄位後新增一個age欄位,設定int not null default 20;
            mysql> alter table user add age int not null default 20 after email;

            -- 在user表的最前面新增一個aa欄位設定為int型別
            mysql> alter table user add aa int first;

    2. 刪除欄位:alter table 表名 drop 被刪除的欄位名
        例如:-- 刪除user表的aa欄位
             mysql> alter table user drop aa;

    3. 修改欄位:alter table 表名 change[modify] 被修改後的欄位資訊
        其中:change可以修改欄位名, modify 不修改
        例如:
        -- 修改user表中age欄位資訊(型別),(使用modify關鍵字的目的不修改欄位名)
        mysql> alter table user modify age tinyint unsigned not null default 20;
        -- 修改user表的num欄位改為mm欄位並新增了預設值(使用change可以改欄位名)
        mysql> alter table user change num mm int not null default 10;

    4. 新增和刪除索引
        -- 為user表中的name欄位新增唯一性索引,索引名為uni_name;
        mysql> alter table user add unique uni_name(name);
        -- 為user表中的email欄位新增普通索引,索引名為index_eamil
        mysql> alter table user add index index_email(email);
        -- 將user表中index_email的索引刪除
        mysql> alter table user drop index index_email;

    5. 更改表名稱:
        ALTER TABLE 舊錶名 RENAME AS 新表名

    6. 更改AUTO_INCREMENT初始值:
        ALTER TABLE 表名稱 AUTO_INCREMENT=1

    7. 更改表型別:
        ALTER TABLE 表名稱 ENGINE="InnoDB"

MySQL資料庫中的表型別一般常用兩種:MyISAM和InnoDB
區別:MyISAM型別的資料檔案有三個frm(結構)、MYD(資料)、MYI(索引)
      MyISAM型別中的表資料增 刪 改速度快,不支援事務,沒有InnoDB安全。

      InnoDB型別的資料檔案只有一個 .frm
      InnoDB型別的表資料增 刪 改速度沒有MyISAM的快,但支援事務,相對安全。

1.15.4 資料的DML操作:新增資料,修改資料,刪除資料

新增資料:
    格式: insert into 表名[(欄位列表)] values(值列表...);

    --標準新增(指定所有欄位,給定所有的值)
    mysql> insert into stu(id,name,age,sex,classid) values(1,'zhangsan',20,'m','lamp138');
    Query OK, 1 row affected (0.13 sec)

    mysql>
    --指定部分欄位新增值
    mysql> insert into stu(name,classid) value('lisi','lamp138');
    Query OK, 1 row affected (0.11 sec)

    -- 不指定欄位新增值
    mysql> insert into stu value(null,'wangwu',21,'w','lamp138');
    Query OK, 1 row affected (0.22 sec)

    -- 批量新增值
    mysql> insert into stu values
        -> (null,'zhaoliu',25,'w','lamp94'),
        -> (null,'uu01',26,'m','lamp94'),
        -> (null,'uu02',28,'w','lamp92'),
        -> (null,'qq02',24,'m','lamp92'),
        -> (null,'uu03',32,'m','lamp138'),
        -> (null,'qq03',23,'w','lamp94'),
        -> (null,'aa',19,'m','lamp138');
    Query OK, 7 rows affected (0.27 sec)
    Records: 7  Duplicates: 0  Warnings: 0
修改操作:
    格式:update 表名 set 欄位1=值1,欄位2=值2,欄位n=值n... where 條件 

    -- 將id為11的age改為35,sex改為m值
    mysql> update stu set age=35,sex='m' where id=11;
    Query OK, 1 row affected (0.16 sec)
    Rows matched: 1  Changed: 1  Warnings: 0

    -- 將id值為12和14的資料值sex改為m,classid改為lamp92
    mysql> update stu set sex='m',classid='lamp92' where id=12 or id=14 --等價於下面
    mysql> update stu set sex='m',classid='lamp92' where id in(12,14);
    Query OK, 2 rows affected (0.09 sec)
    Rows matched: 2  Changed: 2  Warnings: 0
刪除操作:
    格式:delete from 表名 [where 條件]

    -- 刪除stu表中id值為100的資料
    mysql> delete from stu where id=100;
    Query OK, 0 rows affected (0.00 sec)

    -- 刪除stu表中id值為20到30的資料
    mysql> delete from stu where id>=20 and id<=30;
    Query OK, 0 rows affected (0.00 sec)

    -- 刪除stu表中id值為20到30的資料(等級於上面寫法)
    mysql> delete from stu where id between 20 and 30;
    Query OK, 0 rows affected (0.00 sec)

    -- 刪除stu表中id值大於200的資料
    mysql> delete from stu where id>200;
    Query OK, 0 rows affected (0.00 sec)

1.15.5 資料的DQL操作:資料查詢

格式:
select [欄位列表]|* from 表名
[where 搜尋條件]
[group by 分組欄位 [having 子條件]]
[order by 排序 asc|desc]
[limit 分頁引數]
各種查詢:
    mysql> select * from stu;
    +----+----------+-----+-----+---------+
    | id | name     | age | sex | classid |
    +----+----------+-----+-----+---------+
    |  1 | zhangsan |  20 | m   | lamp138 |
    |  2 | lisi     |  20 | m   | lamp138 |
    |  3 | wangwu   |  21 | w   | lamp138 |
    |  4 | zhaoliu  |  25 | w   | lamp94  |
    |  5 | uu01     |  26 | m   | lamp94  |
    |  6 | uu02     |  28 | w   | lamp92  |
    |  7 | qq02     |  24 | m   | lamp92  |
    |  8 | uu03     |  32 | m   | lamp138 |
    |  9 | qq03     |  23 | w   | lamp94  |
    | 10 | aa       |  19 | m   | lamp138 |
    | 11 | sad      |  35 | m   | lamp94  |
    | 12 | tt       |  25 | m   | lamp92  |
    | 13 | wer      |  25 | w   | lamp94  |
    | 14 | xx       |  25 | m   | lamp92  |
    | 15 | kk       |   0 | w   | lamp94  |
    +----+----------+-----+-----+---------+
    15 rows in set (0.00 sec)

    1. where條件查詢
    1. 查詢班級為lamp138期的學生資訊
    mysql> select * from stu where classid='lamp138';

    2. 查詢lamp138期的男生資訊(sex為m)
    mysql> select * from stu where classid='lamp138' and sex='m';

    3. 查詢id號值在10以上的學生資訊
    mysql> select * from  stu where id>10;

    4. 查詢年齡在20至25歲的學生資訊
    mysql> select * from stu where age>=20 and age<=25;
    mysql> select * from stu where age between 20 and 25;

    5. 查詢年齡不在20至25歲的學生資訊
    mysql> select * from stu where age not between 20 and 25;
    mysql> select * from stu where age<20 or age>25;

    6. 查詢id值為1,8,4,10,14的學生資訊
    select * from stu where id in(1,8,4,10,14);
    mysql> select * from stu where id=1 or id=8 or id=4 or id=10 or id=14;

    7. 查詢lamp138和lamp94期的女生資訊
    mysql> select * from stu where classid in('lamp138','lamp94') and sex='w';
    mysql> select * from stu where (classid='lamp138' or classid='lamp94') and sex='w

1.15.6 資料庫授權、備份和恢復

授權:
    格式:grant 允許操作 on 庫名.表名 to 賬號@來源 identified by '密碼';

    --例項:建立zhangsan賬號,密碼123,授權lamp61庫下所有表的增/刪/改/查資料,來源地不限
    mysql> grant select,insert,update,delete on lamp61.* to zhangsan@'%' identified by '123';
    mysql> grant all on *.* to zhangsan@'%' identified by '123';
    Query OK, 0 rows affected (0.00 sec) 

    -- 授權一個使用者(zhangsan)密碼123,可以對所有的庫,所有的表做所有操作。
    mysql> grant all on *.* to zhangsan@'%' identified by '123';
    Query OK, 0 rows affected (0.17 sec)

    --重新整理生效,否則就要重啟MySQL服務才可以。
    mysql> flush privileges;
    Query OK, 0 rows affected (0.00 sec)

    --瀏覽當前MySQL使用者資訊
    mysql> select user,host,password from mysql.user;
    +----------+-----------------+-------------------------------------------+
    | user     | host            | password                                  |
    +----------+-----------------+-------------------------------------------+
    | root     | localhost       | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 |
    | root     | 127.0.0.1       |                                           |
    |          | localhost       |                                           |
    | zhangsan | %               | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 |
    | admin    | 192.168.112.132 | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 |
    +----------+-----------------+-------------------------------------------+
    5 rows in set (0.00 sec)

    -- 移除一些許可權
    -- revoke:只刪除了使用者許可權,但沒有刪除這個使用者
    mysql> revoke insert,delete on *.* from admin@192.168.112.132 identified by'123';

    -- 檢視指定使用者的許可權資訊
    mysql> show grants for xbb@localhost;
    +------------------------------------------------------------------------------------------------------------+
    | Grants for xbb@localhost                                                                                   |
    +------------------------------------------------------------------------------------------------------------+
    | GRANT USAGE ON *.* TO 'xbb'@'localhost' IDENTIFIED BY PASSWORD '*23AE809DDACAF96AF0FD78ED04B6A265E05AA257' |
    +------------------------------------------------------------------------------------------------------------+

    --drop user:刪除了整個使用者及其許可權(包括資料字典中的資料)
    mysql> drop user 'xbb'@'localhost';
    Query OK, 0 rows affected (0.00 sec)

    mysql> select user,host from mysql.user;
    +------------------+-----------+
    | user             | host      |
    +------------------+-----------+
    | root             | 127.0.0.1 |
    | debian-sys-maint | localhost |
    | root             | localhost |
    | root             | wangxg    |
    +------------------+-----------+
    4 rows in set (0.00 sec)
備份與恢復(匯入和匯出)
-- 將lamp138庫匯出
D:\>mysqldump -u root -p lamp138 >lamp138.sql
Enter password:

---- 將lamp138庫中的stu表匯出
D:\>mysqldump -u root -p lamp138 stu >lamp138_stu.sql
Enter password:

-- 將lamp138庫匯入
D:\>mysql -u root -p lamp138<lamp138.sql
Enter password:

-- 將lamp138庫中stu表匯入
D:\>mysql -u root -p lamp138<lamp138_stu.sql
Enter password:

1.15.7 MySQL的多表聯查

  • 表之間的關係有:1對1 1對多 多對多
1. 巢狀查詢:一個查詢的結果是另外sql查詢的條件:
    如:查詢stu表中年齡最大的是誰?
    mysql> select * from stu where age=(select max(age) from stu);
    mysql> select * from stu where age in(select max(age) from stu); --(子查詢結果是多條時使用in查詢)
    +----+------+------+-----+----------+
    | id | name | age  | sex | classid  |
    +----+------+------+-----+----------+
    | 14 | abc  |   33 | w   | python01 |
    +----+------+------+-----+----------+
    1 row in set (0.01 sec)

2. where關聯查詢

    已知:員工personnel表和部門department表,其中員工表中的did欄位為部門表id主鍵關聯。
          查詢所有員工資訊,並顯示所屬部門名稱
    要求:顯示欄位:員工id  部門 姓名
    mysql> select p.id,d.name,p.name from personnel p,department d where p.did = d.id;
        +----+-----------+-----------+
        | id | name      | name      |
        +----+-----------+-----------+
        |  2 | 人事部    | 李玉剛    |
        | 10 | 人事部    | 阿杜      |
        |  4 | 市場部    | 劉歡      |
        。。。。


3. 連線join查詢
    左聯:left join
    右聯:right join
    內聯:inner join

已知如下表所示,商品類別資訊表(具有兩層類別關係,通過pid表示,0表示一級類別)
mysql> select * from type;
+----+-----------+------+
| id | name      | pid  |
+----+-----------+------+
|  1 | 服裝      |    0 |
|  2 | 數碼      |    0 |
|  3 | 男裝      |    1 |
|  4 | 手機      |    2 |
|  5 | 相機      |    2 |
|  6 | 電腦      |    2 |
|  7 | 女裝      |    1 |
|  8 | 童裝      |    1 |
|  9 | 食品      |    0 |
| 10 | 零食      |    9 |
| 11 | 特產      |    9 |
| 12 | 休閒裝    |    1 |
+----+-----------+------+
12 rows in set (0.00 sec)

mysql> desc type;
+-------+------------------+------+-----+---------+----------------+
| Field | Type             | Null | Key | Default | Extra          |
+-------+------------------+------+-----+---------+----------------+
| id    | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name  | varchar(16)      | NO   |     | NULL    |                |
| pid   | int(10) unsigned | YES  |     | NULL    |                |
+-------+------------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

-- 查詢二級類別資訊,並關聯出他們的父類別名稱
mysql> select  t1.id,t1.name,t2.name  from type t1,type t2 where t1.pid!=0 and t1.pid=t2.id;
+----+-----------+--------+
| id | name      | name   |
+----+-----------+--------+
|  3 | 男裝      | 服裝   |
|  4 | 手機      | 數碼   |
|  5 | 相機      | 數碼   |
|  6 | 電腦      | 數碼   |
|  7 | 女裝      | 服裝   |
|  8 | 童裝      | 服裝   |
| 10 | 零食      | 食品   |
| 11 | 特產      | 食品   |
| 12 | 休閒裝    | 服裝   |
+----+-----------+--------+
9 rows in set (0.01 sec)

--統計每個一級類別下都有多少個子類別。
mysql> select t1.id,t1.name,count(t2.id) from type t1,type t2 where t1.pid=0 and t1.id=t2.pid group by t1.id;
+----+--------+--------------+
| id | name   | count(t2.id) |
+----+--------+--------------+
|  1 | 服裝   |            4 |
|  2 | 數碼   |            3 |
|  9 | 食品   |            2 |
+----+--------+--------------+
3 rows in set (0.00 sec)

1.15.8 MySQL的其他操作

1. MySQL的表複製
    複製表結構
    mysql> create table 目標表名 like 原表名;

    複製表資料
    mysql> insert into 目標表名 select * from 原表名; 

2. 資料表的索引
    建立索引
    CREATE INDEX index_name ON table_name (column_list)
    CREATE UNIQUE INDEX index_name ON table_name (column_list)

    刪除索引
    DROP INDEX index_name ON talbe_name

3. mysql檢視
    建立檢視:
    mysql> create view v_t1 as select * from t1 where id>4 and id<11;
    Query OK, 0 rows affected (0.00 sec)

    view檢視的幫助資訊:
    mysql> ? view
    ALTER VIEW
    CREATE VIEW
    DROP VIEW

    檢視檢視:
    mysql> show tables;

    刪除檢視v_t1:
    mysql> drop view v_t1;

4. MySQL的內建函式
    字串處理函式
    ---------------------------------------------
    *concat(s1,s2,…Sn) 連線s1,s2..Sn為一個字串
    insert(str,x,y,instr)將字串str從第xx位置開始,y字串的子字串替換為字串str
    lower(str)將所有的字串變為小寫
    upper(str)將所有的字串變為大寫
    left(str,x)返回字串中最左邊的x個字元
    rigth(str,y)返回字串中最右邊的x個字元
    lpad(str,n,pad)用字串pad對str最左邊進行填充,直到長度為n個字串長度
    rpad(str,n,pad)用字串pad對str最右邊進行填充,直到長度為n個字串長度
    trim(str)  去掉左右兩邊的空格
    ltrim(str) 去掉字串str左側的空格
    rtrim(str) 去掉字串str右側的空格
    repeat(str,x)   返回字串str重複x次
    replace(str,a,b)將字串的的a替換成b
    strcmp(s1,s2)   比較字串s1和s2
    substring(s,x,y)返回字串指定的長度
    *length(str)  返回值為字串str 的長度    

    數值函式
    -----------------------------------------------------
    *abs(x)    返回x的絕對值
    ceil(x)   返回大於x的最小整數值
    floor(x)  返回小於x的最大整數值
    mod(x,y)  返回x/y的取餘結果
    rand()    返回0~1之間的隨機數
    *round(x,y)返回引數x的四捨五入的有y位小數的值
    truncate(x,y) 返回x截斷為y位小數的結果

    日期和時間函式
    ---------------------------------------------------
    curdate()  返回當前日期,按照’YYYY-MM-DD’格式
    curtime()  返回當前時間,當前時間以'HH:MM:SS' 
    *now()      返回當前日期和時間,
    *unix_timestamp(date) 返回date時間的unix時間戳
    from_unixtime(unix_timestamp[,format])    返回unix時間的時間
    week(date)        返回日期是一年中的第幾周
    year(date)      返回日期的年份
    hour(time)      返回time的小時值
    minute(time)    返回日time的分鐘值
    monthname(date) 返回date的月份
    *date_fomat(date,fmt) 返回按字串fmt格式化日期date值
    date_add(date,INTERVAL,expr type) 返回一個日期或者時間值加上一個時間間隔的時間值
    *datediff(expr,expr2)   返回起始時間和結束時間的間隔天數

    //統計時間戳647583423距離當前時間相差天數(生日天數(不考慮年份))
    mysql> select datediff(date_format(from_unixtime(647583423),"2017-%m-%d %h:%i:%s"),now());

    其他常用函式
    ------------------------------------------------------
    *database() 返回當前資料庫名
    version()   返回當前伺服器版本
    user()        返回當前登陸使用者名稱
    inet_aton   返回當前IP地址的數字表示 inet_aton("192.168.80.250");
    inet_ntoa(num) 返回當前數字表示的ip   inet_ntoa(3232256250);
    *password(str)  返回當前str的加密版本
    *md5(str)      返回字串str的md5值

5. MySQL的事務處理
    關閉自動提交功能(開啟手動事務)
    mysql> set autocommit=0;
    從表t1中刪除了一條記錄
    mysql> delete from t1 where id=11;
    此時做一個p1還原點:
    mysql> savepoint p1;
    再次從表t1中刪除一條記錄:
    mysql> delete from t1 where id=10;
    再次做一個p2還原點:
    mysql> savepoint p2;
    此時恢復到p1還原點,當然後面的p2這些還原點自動會失效: 
    mysql> rollback to p1;
    退回到最原始的還原點:
    mysql> rollback;
    回滾

    開啟自動事務提交(關閉手動事務)
    mysql> set autocommit=1;

6. MySQL的觸發器
    格式:1、觸發器的定義:
      CREATE TRIGGER trigger_name trigger_time trigger_event
        ON tbl_name FOR EACH ROW trigger_stmt

      說明:
      # trigger_name:觸發器名稱
      # trigger_time:觸發時間,可取值:BEFORE或AFTER
      # trigger_event:觸發事件,可取值:INSERT、UPDATE或DELETE。
      # tb1_name:指定在哪個表上
      # trigger_stmt:觸發處理SQL語句。

    示例:
        mysql> delimiter $$
        mysql> create trigger del_stu before delete on stu for each row
            -> begin
            ->  insert into stu_bak values(old.id,old.name,old.sex,old.age,old.addtime);
            -> end;
            -> $$
        Query OK, 0 rows affected (0.05 sec)

        mysql> delimiter ;

7. mysql日誌
    開啟日誌: 在mysql配置檔案中開啟:log-bin=mysql-bin

    檢視bin-log日誌:
    mysql>show binary logs;

    檢視最後一個bin-log日誌:
    mysql>show master status;

    此時就會多一個最新的bin-log日誌
    mysql>flush logs;

    檢視最後一個bin日誌.
    mysql>show master status;

    mysql>reset master;
    清空所有的bin-log日誌
    執行檢視bin-log日誌

    備份資料:
    mysqldump -uroot -pwei test -l -F '/tmp/test.sql'
    其中:-F即flush logs,可以重新生成新的日誌檔案,當然包括log-bin日誌 

    // Linux關閉MySQL的命令
    $mysql_dir/bin/mysqladmin -uroot -p shutdown
    // linux啟動MySQL的命令
    $mysql_dir/bin/mysqld_safe &

8、有關慢查詢操作:
    開戶和設定慢查詢時間:
    vi /etc/my.cnf
    log_slow_queries=slow.log
    long_query_time=5
    檢視設定後是否生效
    mysql> show variables like "%quer%"; 
    慢查詢次數:
    mysql> show global status like "%quer%";


9 資料庫的恢復
    1. 首先恢復最後一次的備份完整資料
    [root@localhost mnt]# mysql -u root -p mydemo<mydemo_2017-7-26.sql 
    Enter password: 

    2. 檢視bin-log日誌
    [root@localhost data]# mysqlbinlog --no-defaults mysql-bin.000009;
      查詢到恢復的節點

    3. 執行bin-log日誌檔案,恢復最後一塊的增量資料。 
    [root@localhost data]# mysqlbinlog --no-defaults --stop-position="802" mysql-bin.000009|mysql -u ro

1.16 Python的資料庫支援

1.16.1. 什麼是 PyMySQL?

  • PyMySQL 是在 Python3.x 版本中用於連線 MySQL 伺服器的一個庫,Python2中則使用mysqldb。
  • PyMySQL 遵循 Python 資料庫 API v2.0 規範,幷包含了 pure-Python MySQL 客戶端庫。

1.16.2. PyMySQL安裝

  • PyMySQL下載地址:https://github.com/PyMySQL/PyMySQL。
2.1 使用pip命令進行安裝:
$ pip install PyMySQL
2.2 使用 git 命令下載安裝包安裝(你也可以手動下載):
$ git clone https://github.com/PyMySQL/PyMySQL
$ cd PyMySQL/
$ python3 setup.py install

1.16.3. 資料庫連線

3.1 通過如下程式碼測試資料庫連線
#!/usr/bin/python3

import pymysql

# 開啟資料庫連線
db = pymysql.connect(host="localhost",user="root",password="",db="mydb",charset="utf8")

# 使用 cursor() 方法建立一個遊標物件 cursor
cursor = db.cursor()

# 使用 execute()  方法執行 SQL 查詢 
cursor.execute("SELECT VERSION()")

# 使用 fetchone() 方法獲取單條資料.
data = cursor.fetchone()

print ("Database version : %s " % data)

# 關閉資料庫連線
db.close()
3.2 執行資料查詢
#!/usr/bin/python3

import pymysql

#開啟資料庫連線
db = pymysql.connect(host="localhost",user="root",password="",db="mydb",charset="utf8")

#使用cursor()方法建立一個遊標物件cursor
cursor = db.cursor()

#定義查詢sql語句
#sql = "select * from stu"
sql = "select * from stu where classid='%s'"%("python03")

try:
    # 使用execute()方法執行SQL查詢 
    cursor.execute(sql)

    print("本次查詢條數:",cursor.rowcount)
    '''
    # 使用fetchone()方法獲取單條資料.
    while True:
        data = cursor.fetchone();
        if data == None:
            break;
        print (data)
    '''
    #使用fetchall()獲取所有結果
    alist = cursor.fetchall()
    for vo in alist:
        print(vo)

except Exception as err:
    print("SQL執行錯誤,原因:",err)

# 關閉資料庫連線
db.close()
3.3 執行資料新增
#!/usr/bin/python3

import pymysql

#開啟資料庫連線
db = pymysql.connect(host="localhost",user="root",password="",db="mydb",charset="utf8")

#使用cursor()方法建立一個遊標物件cursor
cursor = db.cursor()

#定義新增sql語句
data = ("uu100",28,'w','python05')
sql = "insert into stu(name,age,sex,classid) values('%s','%d','%s','%s')"%(data)

try:
    # 使用execute()方法執行SQL 
    m = cursor.execute(sql)
    # 事務提交
    db.commit()
    print("成功操作條數:",m)
    #print("成功操作條數:",cursor.rowcount)
except Exception as err:
    #事務回滾
    db.rollback()
    print("SQL執行錯誤,原因:",err)

# 關閉資料庫連線
db.close()
3.4 執行刪除操作
#!/usr/bin/python3

import pymysql

#開啟資料庫連線
db = pymysql.connect(host="localhost",user="root",password="",db="mydb",charset="utf8")

#使用cursor()方法建立一個遊標物件cursor
cursor = db.cursor()

#定義刪除sql語句
sql = "delete from stu where id=%d"%(100)

try:
    # 使用execute()方法執行SQL 
    cursor.execute(sql)
    # 事務提交
    db.commit()
    print("成功刪除條數:",cursor.rowcount)
except Exception as err:
    #事務回滾
    db.rollback()
    print("SQL執行錯誤,原因:",err)

# 關閉資料庫連線
db.close()

資料庫查詢操作:

  • Python查詢Mysql使用 fetchone() 方法獲取單條資料, 使用fetchall() 方法獲取多條資料。
    • fetchone(): 該方法獲取下一個查詢結果集。結果集是一個物件,最後返回None結束
    • fetchall(): 接收全部的返回結果行.
  • rowcount: 這是一個只讀屬性,並返回執行execute()方法後影響的行數。

附錄:pip命令

------------------------------------------------------------
列出已安裝的包:
    $ pip list
    $ pip freeze     # 檢視自己安裝的

安裝軟體(安裝特定版本的package,通過使用==, &gt;=, &lt;=, &gt;, &lt;來指定一個版本號)**
    $ pip install SomePackage
    $ pip install 'Markdown<2.0'
    $ pip install 'Markdown>2.0,<2.0.3'

解除安裝軟體pip uninstall SomePackage
    $ pip uninstall SomePackage

下載所需的軟體包:
    $ pip download SomePackage -d directory 
    例如下載PyMySQL軟體包
    $ pip download PyMySQL -d D:/pypackage

安裝下載好的軟體包檔案
    $ pip install 目錄/軟體包檔名
    如安裝PyMySQL軟體包
    $ pip3.6 install D:/pypackage/PyMySQL-0.7.11-py2.py3-none-any.whl

1.17 圖形使用者介面實戰

  • 本節介紹如何建立Python程式的圖形使用者介面(GUI),也就是那些帶有按鈕和文字框的視窗。
  • 目前支援Python的所謂"GUI工具包"有很多,但沒有一個被認為是標準的,也好,選擇空間大
  • GUI工具包:
工具包名介紹URL地址
Tkinter使用Tk平臺。很容易得到。半標準http://wiki.python.org/moin/TkInter
wxpython基於wxWindows。跨平臺越來越流行http://wxpython.org
PythonWin只能在Windows上使用。http://starship.python.net/crew/mhammond
Java Swing只能用於Python。使用本機的Java GUIhttp://java.sun.com/docs/books/tutorial/uiswing
PyGTK使用GTK平臺,在Linux上很流行http://pygtk.org
PyQt使用Qt平臺,跨平臺http://wiki.python.org/moin/PyQt

1.17.1 安裝:wxpython

 pip install -U wxpython
 --Installing collected packages: six, wxpython
 --Successfully installed six-1.11.0 wxpython-4.0.1
  • 開發步驟:
1. 匯入wx模組
2. 定義一個應用程式物件
3. 建立wx.Frame主視窗物件,設定視窗標題和大小
4. 建立元件、佈局、新增事件處理等操作
5. 通過Frame的show()方法顯示窗體
6. 進入應用程式事件主迴圈

1.17.2 建立並且顯示一個框架

# 匯入wxPython模組
import wx
# 建立應用程式物件
app = wx.App()
win = wx.Frame(None)    #建立一個單獨的視窗
btn=wx.Button(win)  #建立一個按鈕元件
win.Show()          #設定可見
#進入應用程式事件主迴圈
app.MainLoop()

1.17.3 設定標題,新增按鈕

import wx
app = wx.App()
win = wx.Frame(None,title="我的記事本") #建立一個單獨的視窗
loadButton = wx.Button(win,label="Open")
saveButton = wx.Button(win,label="Save")
win.Show()
app.MainLoop()  #進入應用程式事件主迴圈

1.17.4 設定標題,新增按鈕,並簡單佈局

import wx
app = wx.App()
win = wx.Frame(None,title="我的記事本",size=(410,335)) #建立一個單獨的視窗

loadButton = wx.Button(win,label="Open",pos=(225,5),size=(80,25))
saveButton = wx.Button(win,label="Save",pos=(315,5),size=(80,25))

filename = wx.TextCtrl(win,pos=(5,5),size=(210,25))

contents = wx.TextCtrl(win,pos=(5,35),size=(390,260),style=wx.TE_MULTILINE | wx.HSCROLL)

win.Show()

app.MainLoop() #進入應用程式事件主迴圈

1.17.5 元件佈局

import wx
app = wx.App()
win = wx.Frame(None,title="我的記事本",size=(410,335)) #建立一個單獨的視窗
bkg = wx.Panel(win)

#建立元件
loadButton = wx.Button(bkg,label="Open")
saveButton = wx.Button(bkg,label="Save")
filename = wx.TextCtrl(bkg)
contents = wx.TextCtrl(bkg,style=wx.TE_MULTILINE | wx.HSCROLL)

#佈局容器
hbox=wx.BoxSizer() #預設水平佈局
hbox.Add(filename,proportion=1,flag=wx.EXPAND)
hbox.Add(loadButton,proportion=0,flag=wx.LEFT,border=5)
hbox.Add(saveButton,proportion=0,flag=wx.LEFT,border=5)

#佈局容器
vbox=wx.BoxSizer(wx.VERTICAL) #垂直佈局
vbox.Add(hbox,proportion=0,flag=wx.EXPAND|wx.ALL,border=5)
vbox.Add(contents,proportion=1,flag=wx.EXPAND|wx.LEFT|wx.BOTTOM|wx.RIGHT,border=50)

bkg.SetSizer(vbox)

win.Show()
app.MainLoop() #進入應用程式事件主迴圈

1.17.6 為按鈕新增事件並完成其事件處理操作

import wx

#按鈕事件處理函式
def load(event):
    '''載入檔案內容'''
    file=open(filename.GetValue(),"r")
    contents.SetValue(file.read())
    file.close()

def save(event):
    '''保持檔案內容'''
    file=open(filename.GetValue(),"w")
    file.write(contents.GetValue())
    file.close()

#
app = wx.App()
win = wx.Frame(None,title="我的記事本",size=(410,335)) #建立一個單獨的視窗
win.Show()
loadButton = wx.Button(win,label="Open",pos=(225,5),size=(80,25))
saveButton = wx.Button(win,label="Save",pos=(315,5),size=(80,25))

loadButton.Bind(wx.EVT_BUTTON,load)
saveButton.Bind(wx.EVT_BUTTON,save)

filename = wx.TextCtrl(win,pos=(5,5),size=(210,25))

contents = wx.TextCtrl(win,pos=(5,35),size=(390,260),style=wx.TE_MULTILINE | wx.HSCROLL)

app.MainLoop() #進入應用程式事件主迴圈

1.18 階段案例實戰 :《飛機遊戲》

  • 本次開發需要安裝一個Python的遊戲模組:pygame。 方式:pip install pygame

開發步驟如下:

1.18.1 建立遊戲主頁面視窗,並新增滾動背景。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-ccaHcpaT-1603700619117)(https://edu.csdn.net/notebook/python/images/week02/11.png)]

# -*- coding:utf-8 -*-
import pygame
from pygame.locals import *  #pygame使用的各種常量
import time

# 建立遊戲主頁面視窗,並新增滾動背景。

def main():
    '''遊戲的主程式執行函式'''

    #1. 建立視窗:set_mode(解析度=(0,0),標誌=0,深度=0)
    screen = pygame.display.set_mode((512,568),0,0)

    #2. 建立一個遊戲背景圖片(512*1536)
    background = pygame.image.load("./images/bg2.jpg")
    m=-968 #初始化遊戲背景圖片標軸y的值

    while True:
        #繪製點陣圖
        screen.blit(background,(0,m))
        m+=2
        if m>=-200:
            m = -968

        #更新螢幕顯示
        pygame.display.update()

        # 定時睡眠(時鐘)
        time.sleep(0.04)

# 判斷當前是否是主程式,若是就執行主程式。
if __name__ == "__main__":
    main()

1.18.2 新增鍵盤事件處理函式

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-94d6RkfS-1603700619117)(https://edu.csdn.net/notebook/python/images/week02/22.png)]

# -*- coding:utf-8 -*-
import pygame
from pygame.locals import *  #pygame使用的各種常量
import time

# 新增鍵盤事件處理函式。
def key_control(hero_temp):
    ''' 鍵盤控制函式 '''

    #獲取事件,比如按鍵等
    for event in pygame.event.get():
        #判斷是否是點選了退出按鈕
        if event.type == QUIT:
            print("exit")
            exit()

    #獲取按下的鍵(返回的是元組值)
    pressed_keys = pygame.key.get_pressed()
    #檢測是否按下a或者left鍵
    if pressed_keys[K_LEFT] or pressed_keys[K_a]:
        print('left')

    #檢測是否按下d或者right鍵
    elif pressed_keys[K_RIGHT] or pressed_keys[K_d]:
        print('right')

    #檢查是否是空格鍵
    if pressed_keys[K_SPACE]:
        print('space')

def main():
    '''遊戲的主程式執行函式'''

    #1. 建立視窗:set_mode(解析度=(0,0),標誌=0,深度=0)
    screen = pygame.display.set_mode((512,568),0,0)

    #2. 建立一個遊戲背景圖片(512*1536)
    background = pygame.image.load("./images/bg2.jpg")
    m=-968 #初始化遊戲背景圖片標軸y的值

    while True:
        #繪製點陣圖
        screen.blit(background,(0,m))
        m+=2
        if m>=-200:
            m = -968

        # 呼叫鍵盤控制函式
        key_control(None)

        #更新螢幕顯示
        pygame.display.update()

        # 定時睡眠(時鐘)
        time.sleep(0.04)

# 判斷當前是否是主程式,若是就執行主程式。
if __name__ == "__main__":
    main()

1.18.3 放置玩家英雄飛機,並繫結鍵盤事件,實現飛機移動

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-INKpnfss-1603700619118)(https://edu.csdn.net/notebook/python/images/week02/33.png)]

# -*- coding:utf-8 -*-

import pygame
from pygame.locals import *  #pygame使用的各種常量
import time

# 放置玩家英雄飛機,並繫結鍵盤事件,實現飛機移動

class HeroPlane:
    ''' 玩家飛機類(英雄) '''
    def __init__(self, screen_temp):
        self.x = 200
        self.y = 400
        self.screen = screen_temp
        self.image = pygame.image.load("./images/me.png")

    def display(self):
        ''' 繪製玩家到視窗中 '''
        self.screen.blit(self.image, (self.x, self.y))

    def move_left(self):
        ''' 左移動,並判斷防止越界 '''
        self.x -= 5
        if self.x<0:
            self.x=0

    def move_right(self):
        ''' 右移動,並判斷防止越界 '''
        self.x += 5
        if self.x > 406:
            self.x = 406

def key_control(hero_temp):
    ''' 鍵盤控制函式 '''

    #獲取事件,比如按鍵等
    for event in pygame.event.get():
        #判斷是否是點選了退出按鈕
        if event.type == QUIT:
            print("exit")
            exit()

    #獲取按下的鍵(返回的是元組值)
    pressed_keys = pygame.key.get_pressed()
    #檢測是否按下a或者left鍵
    if pressed_keys[K_LEFT] or pressed_keys[K_a]:
        print('left')
        hero_temp.move_left()

    #檢測是否按下d或者right鍵
    elif pressed_keys[K_RIGHT] or pressed_keys[K_d]:
        print('right')
        hero_temp.move_right()

    #檢查是否是空格鍵
    if pressed_keys[K_SPACE]:
        print('space')

def main():
    '''遊戲的主程式執行函式'''

    #1. 建立視窗:set_mode(解析度=(0,0),標誌=0,深度=0)
    screen = pygame.display.set_mode((512,568),0,0)

    #2. 建立一個遊戲背景圖片(512*1536)
    background = pygame.image.load("./images/bg2.jpg")
    m=-968 #初始化遊戲背景圖片標軸y的值

    #3. 建立一個玩家飛機物件
    hero = HeroPlane(screen)

    while True:
        #繪製點陣圖
        screen.blit(background,(0,m))
        m+=2
        if m>=-200:
            m = -968

         #顯示英雄玩家
        hero.display()
        # 鍵盤控制(負責移動玩家)
        key_control(hero)

        #更新螢幕顯示
        pygame.display.update()

        # 定時睡眠(時鐘)
        time.sleep(0.04)

# 判斷當前是否是主程式,若是就執行主程式。
if __name__ == "__main__":
    main()

1.18.4 新增玩家子彈,並實現發射

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-pOTHMYle-1603700619119)(https://edu.csdn.net/notebook/python/images/week02/44.png)]

# -*- coding:utf-8 -*-

import pygame
from pygame.locals import *  #pygame使用的各種常量
import time

# 新增玩家子彈,並實現發射。

class HeroPlane:
    ''' 玩家飛機類(英雄) '''
    def __init__(self, screen_temp):
        self.x = 200
        self.y = 400
        self.screen = screen_temp
        self.image = pygame.image.load("./images/me.png")
        self.bullet_list = [] #儲存發射出去的子彈物件引用

    def display(self):
        ''' 繪製玩家到視窗中 '''

        #遍歷移動子彈
        for bullet in self.bullet_list:
            bullet.display()
            #移動子彈,並判斷是否越界。
            if bullet.move():
                self.bullet_list.remove(bullet)

        self.screen.blit(self.image, (self.x, self.y))


    def move_left(self):
        ''' 左移動,並判斷防止越界 '''
        self.x -= 5
        if self.x<0:
            self.x=0

    def move_right(self):
        ''' 右移動,並判斷防止越界 '''
        self.x += 5
        if self.x > 406:
            self.x = 406
    def fire(self):
        self.bullet_list.append(Bullet(self.screen, self.x, self.y))
        print(len(self.bullet_list))

class Bullet:
    ''' 玩家子彈類 '''
    def __init__(self, screen_temp, x, y):
        self.x = x+51
        self.y = y
        self.screen = screen_temp
        self.image = pygame.image.load("./images/pd.png")

    def display(self):
        self.screen.blit(self.image, (self.x, self.y))

    def move(self):
        self.y-=10
        if self.y<-20:
            return True

def key_control(hero_temp):
    ''' 鍵盤控制函式 '''

    #獲取事件,比如按鍵等
    for event in pygame.event.get():
        #判斷是否是點選了退出按鈕
        if event.type == QUIT:
            print("exit")
            exit()

    #獲取按下的鍵(返回的是元組值)
    pressed_keys = pygame.key.get_pressed()
    #檢測是否按下a或者left鍵
    if pressed_keys[K_LEFT] or pressed_keys[K_a]:
        print('left')
        hero_temp.move_left()

    #檢測是否按下d或者right鍵
    elif pressed_keys[K_RIGHT] or pressed_keys[K_d]:
        print('right')
        hero_temp.move_right()

    #檢查是否是空格鍵
    if pressed_keys[K_SPACE]:
        print('space')
        hero_temp.fire()

def main():
    '''遊戲的主程式執行函式'''

    #1. 建立視窗:set_mode(解析度=(0,0),標誌=0,深度=0)
    screen = pygame.display.set_mode((512,568),0,0)

    #2. 建立一個遊戲背景圖片(512*1536)
    background = pygame.image.load("./images/bg2.jpg")
    m=-968 #初始化遊戲背景圖片標軸y的值

    #3. 建立一個玩家飛機物件
    hero = HeroPlane(screen)

    while True:
        #繪製點陣圖
        screen.blit(background,(0,m))
        m+=2
        if m>=-200:
            m = -968

         #顯示英雄玩家
        hero.display()
        # 鍵盤控制(負責移動玩家)
        key_control(hero)

        #更新螢幕顯示
        pygame.display.update()

        # 定時睡眠(時鐘)
        time.sleep(0.04)

# 判斷當前是否是主程式,若是就執行主程式。
if __name__ == "__main__":
    main()

1.18.5 隨機顯示敵機

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-qPBrAEyI-1603700619120)(https://edu.csdn.net/notebook/python/images/week02/55.png)]

# -*- coding:utf-8 -*-

import pygame
from pygame.locals import *  #pygame使用的各種常量
import time,random

# 顯示敵機。

class HeroPlane:
    ''' 玩家飛機類(英雄) '''
    def __init__(self, screen_temp):
        self.x = 200
        self.y = 400
        self.screen = screen_temp
        self.image = pygame.image.load("./images/me.png")
        self.bullet_list = [] #儲存發射出去的子彈物件引用

    def display(self):
        ''' 繪製玩家到視窗中 '''

        #遍歷移動子彈
        for bullet in self.bullet_list:
            bullet.display()
            #移動子彈,並判斷是否越界。
            if bullet.move():
                self.bullet_list.remove(bullet)

        self.screen.blit(self.image, (self.x, self.y))


    def move_left(self):
        ''' 左移動,並判斷防止越界 '''
        self.x -= 5
        if self.x<0:
            self.x=0

    def move_right(self):
        ''' 右移動,並判斷防止越界 '''
        self.x += 5
        if self.x > 406:
            self.x = 406
    def fire(self):
        self.bullet_list.append(Bullet(self.screen, self.x, self.y))
        print(len(self.bullet_list))

class Bullet:
    ''' 玩家子彈類 '''
    def __init__(self, screen_temp, x, y):
        self.x = x+51
        self.y = y
        self.screen = screen_temp
        self.image = pygame.image.load("./images/pd.png")

    def display(self):
        self.screen.blit(self.image, (self.x, self.y))

    def move(self):
        self.y-=10
        if self.y<-20:
            return True

class EnemyPlane:
    """敵機的類"""
    def __init__(self, screen_temp):
        self.x = random.choice(range(408))
        self.y = -75
        self.screen = screen_temp
        self.image = pygame.image.load("./images/e2.png")

    def display(self):
        self.screen.blit(self.image, (self.x, self.y))

    def move(self):
        self.y += 4


def key_control(hero_temp):
    ''' 鍵盤控制函式 '''

    #獲取事件,比如按鍵等
    for event in pygame.event.get():
        #判斷是否是點選了退出按鈕
        if event.type == QUIT:
            print("exit")
            exit()

    #獲取按下的鍵(返回的是元組值)
    pressed_keys = pygame.key.get_pressed()
    #檢測是否按下a或者left鍵
    if pressed_keys[K_LEFT] or pressed_keys[K_a]:
        print('left')
        hero_temp.move_left()

    #檢測是否按下d或者right鍵
    elif pressed_keys[K_RIGHT] or pressed_keys[K_d]:
        print('right')
        hero_temp.move_right()

    #檢查是否是空格鍵
    if pressed_keys[K_SPACE]:
        print('space')
        hero_temp.fire()

def main():
    '''遊戲的主程式執行函式'''

    #1. 建立視窗:set_mode(解析度=(0,0),標誌=0,深度=0)
    screen = pygame.display.set_mode((512,568),0,0)

    #2. 建立一個遊戲背景圖片(512*1536)
    background = pygame.image.load("./images/bg2.jpg")
    m=-968 #初始化遊戲背景圖片標軸y的值

    #3. 建立一個玩家飛機物件
    hero = HeroPlane(screen)

    #4. 定義用於存放敵機列表
    enemylist = []

    while True:
        #繪製點陣圖
        screen.blit(background,(0,m))
        m+=2
        if m>=-200:
            m = -968

         #顯示英雄玩家
        hero.display()
        # 鍵盤控制(負責移動玩家)
        key_control(hero)

        #隨機輸出敵機
        if random.choice(range(50))==10:
            enemylist.append(EnemyPlane(screen))
        #遍歷所有敵機,顯示敵機,移動敵機
        for em in enemylist:
            em.display()
            em.move()

        #更新螢幕顯示
        pygame.display.update()

        # 定時睡眠(時鐘)
        time.sleep(0.04)

# 判斷當前是否是主程式,若是就執行主程式。
if __name__ == "__main__":
    main()

1.18.6 實現敵機與子彈的碰撞檢測

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-gK0TBpJN-1603700619121)(https://edu.csdn.net/notebook/python/images/week02/66.png)]

# -*- coding:utf-8 -*-

import pygame
from pygame.locals import *  #pygame使用的各種常量
import time,random

# 實現敵機與子彈的碰撞檢測。

class HeroPlane:
    ''' 玩家飛機類(英雄) '''
    def __init__(self, screen_temp):
        self.x = 200
        self.y = 400
        self.screen = screen_temp
        self.image = pygame.image.load("./images/me.png")
        self.bullet_list = [] #儲存發射出去的子彈物件引用

    def display(self):
        ''' 繪製玩家到視窗中 '''

        #遍歷移動子彈
        for bullet in self.bullet_list:
            bullet.display()
            #移動子彈,並判斷是否越界。
            if bullet.move():
                self.bullet_list.remove(bullet)

        self.screen.blit(self.image, (self.x, self.y))


    def move_left(self):
        ''' 左移動,並判斷防止越界 '''
        self.x -= 5
        if self.x<0:
            self.x=0

    def move_right(self):
        ''' 右移動,並判斷防止越界 '''
        self.x += 5
        if self.x > 406:
            self.x = 406
    def fire(self):
        self.bullet_list.append(Bullet(self.screen, self.x, self.y))
        print(len(self.bullet_list))

class Bullet:
    ''' 玩家子彈類 '''
    def __init__(self, screen_temp, x, y):
        self.x = x+51
        self.y = y
        self.screen = screen_temp
        self.image = pygame.image.load("./images/pd.png")

    def display(self):
        self.screen.blit(self.image, (self.x, self.y))

    def move(self):
        self.y-=10
        if self.y<-20:
            return True

class EnemyPlane:
    """敵機的類"""
    def __init__(self, screen_temp):
        self.x = random.choice(range(408))
        self.y = -75
        self.screen = screen_temp
        self.image = pygame.image.load("./images/e"+str(random.choice(range(3)))+".png")

    def display(self):
        self.screen.blit(self.image, (self.x, self.y))

    def move(self,hero):
        self.y += 4
        #遍歷玩家的子彈,並做碰撞檢測
        for bo in hero.bullet_list:
            if bo.x>self.x+12 and bo.x<self.x+92 and bo.y>self.y+20 and bo.y<self.y+60:
                hero.bullet_list.remove(bo)
                return True
        #判斷敵機是否越界
        if self.y>512:
            return True;

def key_control(hero_temp):
    ''' 鍵盤控制函式 '''

    #獲取事件,比如按鍵等
    for event in pygame.event.get():
        #判斷是否是點選了退出按鈕
        if event.type == QUIT:
            print("exit")
            exit()

    #獲取按下的鍵(返回的是元組值)
    pressed_keys = pygame.key.get_pressed()
    #檢測是否按下a或者left鍵
    if pressed_keys[K_LEFT] or pressed_keys[K_a]:
        print('left')
        hero_temp.move_left()

    #檢測是否按下d或者right鍵
    elif pressed_keys[K_RIGHT] or pressed_keys[K_d]:
        print('right')
        hero_temp.move_right()

    #檢查是否是空格鍵
    if pressed_keys[K_SPACE]:
        print('space')
        hero_temp.fire()

def main():
    '''遊戲的主程式執行函式'''

    #1. 建立視窗:set_mode(解析度=(0,0),標誌=0,深度=0)
    screen = pygame.display.set_mode((512,568),0,0)

    #2. 建立一個遊戲背景圖片(512*1536)
    background = pygame.image.load("./images/bg2.jpg")
    m=-968 #初始化遊戲背景圖片標軸y的值

    #3. 建立一個玩家飛機物件
    hero = HeroPlane(screen)

    #4.定義用於存放敵機列表
    enemylist = []

    while True:
        #繪製點陣圖
        screen.blit(background,(0,m))
        m+=2
        if m>=-200:
            m = -968

         #顯示英雄玩家
        hero.display()
        # 鍵盤控制(負責移動玩家)
        key_control(hero)

        #隨機輸出敵機
        if random.choice(range(50))==10:
            enemylist.append(EnemyPlane(screen))

        #遍歷所有敵機,顯示敵機,移動敵機,並與玩家子彈碰撞檢測
        for em in enemylist:
            em.display()
            if em.move(hero):
                enemylist.remove(em)

        #更新螢幕顯示
        pygame.display.update()

        # 定時睡眠(時鐘)
        time.sleep(0.04)

# 判斷當前是否是主程式,若是就執行主程式。
if __name__ == "__main__":
    main()

1.19 Python擴充套件內容

① python中yield關鍵字的使用:

  • yield 是一個類似 return 的關鍵字,只是這個函式返回的是個生成器
  • 當你呼叫這個函式的時候,函式內部的程式碼並不立馬執行 ,這個函式只是返回一個生成器物件
  • 當你使用for進行迭代的時候,函式中的程式碼才會執行
  • 生成器特點:可迭代;只能讀取一次;實時生成資料,不全存在記憶體中。
def fun():
    yield "aaa"
    yield "bbb"
    yield "ccc"

#返回可迭代物件(生成器)
a = fun()
print(a) # <generator object fun at 0x10f26e990>

#可以將迭代物件轉成列表
# b = list(a)
# print(b) #['aaa', 'bbb', 'ccc']

#遍歷(迭代)輸出,注意:只能讀取一次
for i in a:
    print(i)

'''
aaa
bbb
ccc
'''
  • 案例:
import json

#案例一、這是一段過程化程式碼編寫:
str= '[{"name":"zhangsan","age":22},{"name":"lisi","age":19},{"name":"wangwu","age":24}]'
data = json.loads(str) #解碼JSON資料
# 過濾出年齡大於20歲以上的資訊,並輸出
for item in data:
    if item['age']>20:
        #輸出資料
        print('-' * 20)
        print(item['name'],":",item['age'])

'''
#輸出結果:
--------------------
zhangsan : 22
--------------------
wangwu : 24
'''

#案例二:程式碼拆分(將資料的處理封裝成函式):
def fun1():
    str= '[{"name":"zhangsan","age":22},{"name":"lisi","age":19},{"name":"wangwu","age":24}]'
    data = json.loads(str) #解碼JSON資料
    #過濾出年齡大於20歲以上的資訊,並輸出
    dlist = []
    for item in data:
        if item['age']>20:
            #將過濾出來的資料放置到dlist中
            print('-' * 20)
            dlist.append(item)

    return dlist

# 使用(輸出資料)
for i in fun1():
    print(i['name'], ":", i['age'])


'''
#輸出結果:
--------------------
--------------------
wangwu : 24
wangwu : 24
'''


#案例三:程式碼拆分(使用yield返回生成器):
def fun1():
    str= '[{"name":"zhangsan","age":22},{"name":"lisi","age":19},{"name":"wangwu","age":24}]'
    data = json.loads(str) #解碼JSON資料
    #過濾出年齡大於20歲以上的資訊,並輸出
    for item in data:
        if item['age']>20:
            #將過濾出來的資料放置到dlist中
            print('-' * 20)
            yield item

# 使用(輸出資料)
for i in fun1():
    print(i['name'], ":", i['age'])


'''
#輸出結果:
--------------------
zhangsan : 22
--------------------
wangwu : 24

'''

② 裝飾器的使用:

  • python裝飾器就是用於擴充原來函式功能的一種函式,這個函式的特殊之處在於它的返回值也是一個函式,

  • 使用python裝飾器的好處就是在不用更改原函式的程式碼前提下給函式增加新的功能

  • 無引數的裝飾器例項

# 無引數的裝飾器例項
def deco(dd):
    def _deco():
        print("start....")
        dd()
        print("end.....")
    return _deco

@deco
def demo():
    print("demo()............")


if __name__ == "__main__":
    d = demo
    d()
    #demo()
  • 輸出結果
start....
demo()............
end.....
# 帶引數的裝飾器例項
def deco(func):
    def _deco(a, b):
        print("before myfunc() called.")
        ret = func(a, b)
        print("  after myfunc() called. result: %s" % ret)
        return ret
    return _deco

@deco
def myfunc(a, b):
    print(" myfunc(%s,%s) called." % (a, b))
    return a + b

if __name__ == "__main__":
    myfunc(1, 2)
    myfunc(3, 4)
  • 輸出結果
before myfunc() called.
 myfunc(1,2) called.
  after myfunc() called. result: 3
before myfunc() called.
 myfunc(3,4) called.
  after myfunc() called. result: 7

相關文章