2018-2019-2 20189206 Python3學習
python3簡明教程學習
基本概念
腳本文件:
腳本文件英文為Script。實際上腳本就是程序,一般都是由應用程序提供的編程語言。應用程序包括瀏覽器(javaScript、VBScript)、多媒體創作工具,應用程序的宏和創作系統的批處理語言也可以歸入腳本之類。
腳本文件類似於DOS操作系統中的批處理文件,它可以將不同的命令組合起來,並按確定的順序自動連續地執行。腳本文件是文本文件,用戶可使用任一文本編輯器來創建腳本文件。
解釋器:
解釋器(英語:Interpreter),又譯為直譯器,是一種電腦程序,能夠把高級編程語言一行一行直接轉譯運行。解釋器不會一次把整個程序轉譯出來,只像一位“中間人”,每次運行程序時都要先轉成另一種語言再作運行,因此解釋器的程序運行速度比較緩慢。它每轉譯一行程序敘述就立刻運行,然後再轉譯下一行,再運行,如此不停地進行下去。
解釋器
python是一個腳本語言,可以在python解釋器中直接寫代碼或者將代碼寫到一個文件(腳本文件)然後執行這個文件。
可以用兩種方式使用python語言:
- 在shell中輸入python即可進入交互界面,交互界面中即可運行。
- 在vim編輯器中,創建一個.py的文件,並輸入代碼如下圖所示
- 代碼中的前兩個字符`#!`稱為shebang告訴shell使用python解釋器執行下面的代碼,同時需要為腳本文件添加可執行權限,最後執行文件即可。
模塊
模塊包含了可以復用的代碼文件,包含了不同的函數定義,變量。模塊文件通常以.py為擴展名,使用之前先需要導入它。
python基本的數據類型和變量
python的關鍵字必須完全按照下面來拼寫
python不需要為變量指定數據類型,可以直接寫出abc = 1
同時python的字符串用單引號或雙引號括起來即可。
從鍵盤讀取輸入
input()
函數可以實現從鍵盤讀取輸入。
實現了從鍵盤讀取一個數字並且檢查這個數字是否小於100,運行結果如下圖所示
計算投資:
在看代碼時不太能看懂輸出語句的格式,對比執行後的結果
print("Year {} Rs. {:.2f}".format(year, value))
Year 1 Rs. 11400.00
可以看到,大括號和其中的字符會被替換成傳入.format()
中的變量的值,其中{:.2f}
看不懂的地方涉及到函數str.format()是一個強大的格式化函數
通過位置
In [1]: '{0},{1}'.format('kzc',18)
Out[1]: 'kzc,18'
In [2]: '{},{}'.format('kzc',18)
Out[2]: 'kzc,18'
In [3]: '{1},{0},{1}'.format('kzc',18)
Out[3]: '18,kzc,18'
通過關鍵字參數:即大括號中包含對應的參數名
通過對象屬性
class Person:
def __init__(self,name,age):
self.name,self.age = name,age
def __str__(self):
return 'This guy is {self.name},is {self.age} old'.format(self=self)
In [2]: str(Person('kzc',18))
Out[2]: 'This guy is kzc,is 18 old'
括號中的參數{:5d} {:7.2f}
分別表示,替換為5個字節寬度的整數;替換為7個字節寬度並顯示小數點後兩位的浮點數。
單行定義多個變量或賦值
元組(truple)利用逗號創建元組,例如a , b = b, a
在賦值語句的右邊我們創建了一個元組,稱為元組封裝;賦值語句左邊則是元組拆封。
>>> data = ("shiyanlou", "China", "Python")
>>> name, country, language = data
也就是說,data,(name, country, language)
是兩個封裝,而第二條語句對data進行了拆封。
---
運算符和表達式
運算符
- 數學操作符
+
-
/
只要有一個操作符是浮點數,結果就會是浮點數。使用//
將會返回商的整數部分。%
求余運算符
計算月份和天數
divmod()函數
python divmod() 函數把除數和余數運算結果結合起來,返回一個包含商和余數的元組(a // b, a % b)。
- 關系運算符與其他高級語言一致
- 邏輯運算符 and or not
邏輯運算符的優先級又低於關系運算符,在它們之中,not 具有最高的優先級,or 優先級最低,所以 A and not B or C 等於 (A and (notB)) or C
2 > 1 and not 3 > 5 or 4
這條語句可以看作是((2 > 1) and (not (3 > 5))) or 4
其中 2 > 1
為真 (not (3 > 5))
也為真,故返回 True
程序理解
#!/usr/bin/env python3
sum = 0
for i in range(1, 11):
sum += 1.0 / i
print("{:2d} {:6.4f}".format(i , sum))
所涉及函數
python range()函數用法
range(start, stop[, step])
參數說明:
start: 計數從 start 開始。默認是從 0 開始。例如range(5)等價於range(0, 5);
stop: 計數到 stop 結束,但不包括 stop。例如:range(0, 5) 是[0, 1, 2, 3, 4]沒有5
step:步長,默認為1。例如:range(0, 5) 等價於 range(0, 5, 1)
所以在上面代碼中的for循環,即i從1開始,到10結束,其中不包含11;每循環一次進行一次運算,同時打印i和sum的值。
#!/usr/bin/env python3
import math
a = int(input("Enter value of a: "))
b = int(input("Enter value of b: "))
c = int(input("Enter value of c: "))
d = b * b - 4 * a * c
if d < 0:
print("ROOTS are imaginary")
else:
root1 = (-b + math.sqrt(d)) / (2 * a)
root2 = (-b - math.sqrt(d)) / (2 * a)
print("Root 1 = ", root1)
print("Root 2 = ", root2)
以上是一個求解二次方程的代碼。
#!/usr/bin/env python3
basic_salary = 1500
bonus_rate = 200
commission_rate = 0.02
numberofcamera = int(input("Enter the number of inputs sold: "))
price = float(input("Enter the price of camera: "))
bonus = (bonus_rate * numberofcamera)
commission = (commission_rate * price * numberofcamera)
print("Bonus= {:6.2f}".format(bonus))
print("Commission = {:6.2f}".format(commission))
print("Gross salary = {:6.2f}".format(basic_salary + bonus + commission))
運行結果如下:
math模塊調用的方法
- math.pi是一個模塊變量不能當作函數調用使用
- math.sqrt() 是求平方根
if-else
語法格式:
if expression:
do this
else:
do this
或
if expression:
do this
elif experssion:
do this
else:
do this
註意if後面表達式的:不能少
if後面的表達式為真將執行縮進的所有行,要保證縮進的正確
while循環
語法格式
while condition:
statement1
statement2
要執行的語句必須以正確的縮進放在while語句下面,在表達式condition為真時執行
斐波那契數列實現
#!/usr/bin/env python3
a, b = 0, 1
while b < 100:
print(b, end=' ')
a, b = b, a + b
print()
對於語句a, b = b, a + b
可以理解為Python會先對復制右邊的表達式求值然後將值賦給左邊的變量。即將b的值賦給a,a+b的值賦給b。
print()函數除了打印默認字符外,還會打印一個換行符,所以每次調用print()就會換一次行,利用end參數來替換換行符,如上代碼中print(b, end=‘ ‘)
冪級數實現
#!/usr/bin/env python3
x = float(input("Enter the value of x: "))
n = term = num = 1
result = 1.0
while n <= 100:
term *= x / n
result += term
n += 1
if term < 0.0001:
break
print("No of Times= {} and Sum= {}".format(n, result))
乘法表
#!/usr/bin/env python3
i = 1
print("-" * 50)
while i < 11:
n = 1
while n <= 10:
print("{:5d}".format(i * n), end=' ')
n += 1
print()
i += 1
print("-" * 50)
以上代碼是嵌套循環的代碼,從其運行結果可以看出print("-" * 50)
的作用
數據結構:列表
列表中的元素不必是同一類型,中間用逗號分隔。
a[256,1,23,‘china‘,‘love‘]
其中每一位都有對應的下標,從0開始,可以利用a[4]對應‘love’使用負數索引,就會從尾部開始計數。
切片不會改變正在操作的列表,切片操作會返回其子列表,即一個新的列表副本。
例如: a[1:-2] 表示 [1,23]
a[:-2]則表示[256,1,23]
Python 中有關下標的集合都滿足左閉右開原則,切片中也是如此,也就是說集合左邊界值能取到,右邊界值不能取到。
切片長度就是兩個索引之差
[-1:-5]可以取到全部元素,但[-5:-1]取不到列表中的最後一個值。
切片的上邊界大於下邊界時,返回空列表;一個過大的索引值將被列表的實際長度所代替
可以檢驗某個值是否在列表中
‘cool‘ ia a
內建函數len()可以獲得列表長度
列表允許嵌套
for循環
range()函數可以在for循環需要一個數值序列時使用,具體用法前面提到過。
在循環後面選擇else語句,它將會在循環執行完畢後執行
數據結構
Python有許多內建的數據結構
其中包括列表、元組、
列表有關內容
列表a的建立:
a = [23, 45, 1, -3434, 43624356, 234]
向列表添末尾加元素:
a.append(45)
添加元素 45 到列表末尾。向列表任何位置添加元素:
a.insert()方法
a.insert(0,1)
在列表0的位置添加元素1
列表計算指定值方法:count(s)會返回列表元素中s的數量
移除任意指定值:remove(s)將會移除在列表中的s值
刪除指定位置的值:del()
翻轉列表:reverse()
列表排序:sort()前提是列表的元素是可比較的
將列表用作棧和隊列
pop(i)方法會將第i個元素出棧,例如a.pop(0)將第一個元素彈出列表
- 列表推導式為從序列中創建列表提供了一個簡單的方法
- 列表推導式由包含一個表達式的中括號組成,表達式後面跟隨一個 for 子句,之後可以有零或多個 for 或 if 子句,結果是一個列表。列表推導式也可以嵌套
squares = [x**2 for x in range(10)]
該語句組成的序列是[0,1,4,9,16,25,36,47,64,81][(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
元組
元組是由數個逗號分隔的值所組成,可以對任何一個元組執行拆封操作並賦值給多個變量。
元組是不可變類型,元組內無法進行添加或刪除任何值得操作。
- 要創建只有一個元素的元組,在值得後面跟一個逗號
a = 321,
相當於(321,)
內建函數type()可以知道任意變量的數據類型;len()可以查詢任意序列類型數據長度
集合
集合是一個無序不重復元素的集。基本功能有關系測試和消除重復元素。集合同時還支持數學運算。
大括號或set()函數可以用來創建集合。
a = set(‘abracadabra‘)
得到的a集合是去重後的字母
字典
字典是無序鍵值對的集合,同一個字典內的鍵必須是互不相同的。鍵與值之間利用:分隔。用鍵來檢索存儲在字典中的值。
data
{'kushal': 'Fedora', 'Jace': 'Mac', 'kart_': 'Debian'}
查找字典中鍵對應的值
data['kart_']
'Debian'
刪除字典中任意指定的鍵值對
del data['kushal']
查詢指定關鍵字是否在字典中
'ShiYanLou' in data
遍歷字典
items()方法
for x,y in data.items():
print("{} uses {}".format(x,y))
向字典中元素多次添加數據
dict.setdefault(key, default)
索引鍵,如果不存在將返回指定的default值
dict.get(key, default)
在便利列表的同時獲得元素的索引值,使用enumerate()
for i, j in enumerate(['a', 'b', 'c']):
此時,列表的索引值將會存放在變量i中
字典中的鍵必須是不可變類型,比如列表就不能作為鍵。
輸入學生的三科成績計算是否通過考試
運行結果
代碼分析
建立的data字典以學生的姓名作為鍵,對應的列表中包含的三門成績作為對應學生的成績,也就是字典的值。data[name] = marks
就是一個創建字典的過程,將對應的列表作為值與姓名形成鍵值對。3
字符串
當輸入幾行字符串並且希望行尾換行符自動包含到字符串中,使用三對引號"""....."""
或‘‘‘....‘‘‘
字符串的內建方法
s.split() 分隔字符串
語法方法:
str.split(str="", num=string.count(str)).參數
str -- 分隔符,默認為所有的空字符,包括空格、換行(\n)、制表符(\t)等。
num -- 分割次數。默認為 -1, 即分隔所有。返回值
返回分割後的字符串列表。title()返回字符串的標題版本,即單詞首字母大寫其余字母小寫
upper() 返回字符串的全部大寫版本
lower()返回字符串的全部小寫版本
swapcase() 返回字符串大小寫交換後的版本
isalnum() 檢查所有字符是否只包含數字和字母
isal
-pha() 檢查字符串是否只有字母join() 使用指定字符連接多個字符串
"-".join("GNU/Linux is great".split())
‘GNU/Linux-is-great‘lstrip(chars)或rstrip(chars) 對字符串左或右剝離
find()可以找到字符串中第一個匹配的字符串
檢查回文數
將字符串倒序的方式 z = s[::-1]
這是前面提到的切片的方法,可以對列表、元組等使用。
假如 a = (1,2,3,4,5)
那麽 a[:] a[::] 都代表(1,2,3,4,5)使用默認值a[0:len(a):1]
前面提到過a[0:2]表示a(1,2)
在本題中a[::-1]表示步長為負數,從序列的最後一個元素開始切片,即倒序
函數
定義一個函數
使用關鍵字def定義函數
def 函數名(參數):
語句1
語句2
將回文判斷寫成一個函數
#!/usr/bin/env python3
def palindrome(s):
return s == s[::-1]
if __name__ == '__main__':
s = input("Enter a string: ")
if palindrome(s):
print("Yay a palindrome")
else:
print("Oh no, not a palindrome")
在這裏很疑惑 name == ‘main‘ 的作用是什麽,參考一篇博客,明白__name__是函數的內置變量,詳細參考博客https://blog.csdn.net/xyisv/article/details/78069129
局域或全局變量
在函數中創建的變量是局域變量,只在函數中可用,函數完成時銷毀。同樣在函數中,變量出現在表達式等號之前,就會被當做局部變量。
使用global關鍵字,對函數中的a標誌為全局變量,讓函數內部使用全局變量a,那麽整個程序中出現a都將是一樣的。
默認參數值
函數參數變量可以有默認值,如果對指定的參數變量沒有給出任何值,則會賦其任意值。
def test(a , b=-99):
if a > b:
return True
else:
return False
需要註意的是:
- 具有默認值的參數後面不能再有普通參數
高階函數
高階函數或仿函數是可以接受函數作為參數的函數
map函數
它接受一個函數和一個序列(叠代器)作為輸入,然後對序列(叠代器)的每一個值應用這個函數,返回一個序列(叠代器),其包含應用函數後的結果。
lst = [1, 2, 3, 4, 5]
return num * num
print(list(map(square, lst)))
[1, 4, 9, 16, 25]
文件處理
文件打開
使用open()函數打開文件,需要兩個參數,第一個是文件路徑或文件名;第二是文件的打開方式
- r 只讀 (默認模式)
- w 寫入 刪除文件內所有內容,打開文件進行寫入
- a 追加 寫入到文件中的數據添加到末尾
文件關閉
使用close()關閉文件
文件讀取
read()方法一次性讀取整個文件。
read()有一個可選參數size用來返回指定字符串長度,如果沒有指定size或size為負數,會讀取整個文件
- readline()每次讀取文件的一行
- readlines()讀取所有行到一個列表中
文件寫入
write()方法打開文件然後隨便寫入一些文本
拷貝文本文件到另一個給定文本文件
#!/usr/bin/env python3
import sys
if len(sys.argv) < 3:
print("Wrong parameter")
print("./copyfile.py file1 file2")
sys.exit(1)
f1 = open(sys.argv[1])
s = f1.read()
f1.close()
f2 = open(sys.argv[2], 'w')
f2.write(s)
f2.close()
用到了sys模塊的sys.argv函數,一開始不明的到底這個函數的功能是什麽,參考了一篇博客,了解到sys.argv其實是外部命令與程序內部的橋梁,是一個列表,所以可以通過argv[]進行調用。
https://www.cnblogs.com/aland-1415/p/6613449.html
運行結果如圖所示:
異常
在程序執行過程中發生的任何錯誤都是異常。每個異常顯示一些相關的錯誤信息。
NameError訪問一個未定義變量時會發生NameError異常
TypeError當操作或函數應用於不適當類型的對象時引發
處理異常
使用try...except
快處理異常。
首先,執行 try 子句 (在 try 和 except 關鍵字之間的部分)。
如果沒有異常發生,except 子句 在 try 語句執行完畢後就被忽略了。
如果在 try 子句執行過程中發生了異常,那麽該子句其余的部分就會被忽略。
如果異常匹配於 except 關鍵字後面指定的異常類型,就執行對應的 except 子句。然後繼續執行 try 語句之後的代碼。
如果發生了一個異常,在 except 子句中沒有與之匹配的分支,它就會傳遞到上一級 try 語句中。
如果最終仍找不到對應的處理語句,它就成為一個 未處理異常,終止程序運行,顯示提示信息。
一個空的except()語句可以捕獲任何異常。
拋出異常
使用raise()語句拋出異常
定義清理行為
try語句還有另一個可選的finally字句,在於定義任何情況下都一定要執行的功能。
不管有沒有發生異常,finally 子句 在程序離開 try 後都一定會被執行。當 try 語句中發生了未被 except 捕獲的異常(或者它發生在 except 或 else 子句中),在 finally 子句執行完後它會被重新拋出。
類
定義方式
class nameoftheclass(parent_class):
statement1
statement2
statement3
類的實例
x = MyClass()
以上類的實例用於創建一個空對象,創建一個有初始狀態的類,需要用到方法 init()進行初始化。
繼承
當一個類繼承另一個類時,它將繼承父類的所有功能(如變量和方法)。這有助於重用代碼。
繼承方式:
class Person(object):
def init(self,name):
def get_details(self):
class Student(Person):
class Teacher(Person):
有了init方法後,在創建類的對象時,不需要調用init方法,直接調用類的初始化方法即可。
person1 = Person('Sachin')
student1 = Student('Kushal', 'CSE', 2005)
teacher1 = Teacher('Prashad', ['C', 'C++'])
刪除對象
del s
來刪除對象
裝飾器
你可能想要更精確的調整控制屬性訪問權限,你可以使用 @property 裝飾器,@property 裝飾器就是負責把一個方法變成屬性調用的。
模塊
模塊是包括 Python 定義和聲明的文件。文件名就是模塊名加上 .py 後綴。__name__全局變量可以得到模塊的模塊名。
模塊內的函數必須要用模塊名來訪問。
bars.hashbar(10)
bars.simplebar(10)
bars.starbar(10)
包
含有__init__.py文件的目錄可以用來作為一個包,其中目錄裏的所有.py文件都是這個包的子模塊
如果 init.py 文件內有一個名為 all 的列表,那麽只有在列表內列出的名字將會被公開。
默認模塊
- os模塊 提供了與操作系統相關的功能
- getuid() 函數返回當前進程的有效用戶 id
- getpid() 函數返回當前進程的 id。getppid() 返回父進程的 id
- uname() 函數返回識別操作系統的不同信息,在 Linux 中它返回的詳細信息可以從 uname -a 命令得到。
- getcwd() 函數返回當前工作目錄。chdir(path) 則是更改當前目錄到 path。
- Requests模塊
- 屬於第三方模塊,使用前需要安裝
sudo apt-get update
sudo apt-get install python3-pip
sudo pip3 install requests- get()方法可以獲取任意一個網頁
從指定URL下載文件的程序
#!/usr/bin/env python3
import requests
def download(url):
# 檢查 URL 是否存在
try:
req = requests.get(url)
except requests.exceptions.MissingSchema:
print('Invalid URL "{}"'.format(url))
return
# 檢查是否成功訪問了該網站
if req.status_code == 403:
print('You do not have the authority to access this page.')
return
filename = url.split('/')[-1]
with open(filename, 'w') as fobj:
fobj.write(req.content.decode('utf-8'))
print("Download over.")
if __name__ == '__main__':
url = input('Enter a URL: ')
download(url)
conllections模塊
counter
counter是一個有助於hashable對象計數的dict子類。它是一個無序的集合,其中 hashable 對象的元素存儲為字典的鍵,它們的計數存儲為字典的值,計數可以為任意整數,包括零和負數。
- elements() 方法 依照計數重復重復元素相同次數,元素順序是無序的。
- most_common() 方法返回最常見的元素及其計數,順序為最常見到最少。
defaultdict
defaultdict() 第一個參數提供了 default_factory 屬性的初始值,默認值為 None,default_factory 屬性值將作為字典的默認數據類型。所有剩余的參數與字典的構造方法相同,包括關鍵字參數。
namedtuple
命名元組有助於對元組每個位置賦予意義,並且讓我們的代碼有更好的可讀性和自文檔性。你可以在任何使用元組地方使用命名元組。在例子中我們會創建一個命名元組以展示為元組每個位置保存信息。
叠代器、生成器、裝飾器
叠代器
_iter__(),返回叠代器對象自身。這用在 for 和 in 語句中。
next(),返回叠代器的下一個值。如果沒有下一個值可以返回,那麽應該拋出 StopIteration 異常。
生成器
生成器是更簡單的創建叠代器的方法,這通過在函數中使用 yield 關鍵字完成。
def counter_generator(low, high):
while low <= high:
yield low
low += 1
for i in counter_generator(5,10):
print(i, end=' ')
5 6 7 8 9 10
在 While 循環中,每當執行到 yield 語句時,返回變量 low 的值並且生成器狀態轉為掛起。在下一次調用生成器時,生成器從之前凍結的地方恢復執行然後變量 low 的值增一。也就是說,在下一次執行生成器前,low的值不會改變。
虛擬Python環境virtualenv
安裝兩個不用的虛擬環境,並激活source virt1/bin/activate
安裝redis
這個Python模塊
安裝另一個虛擬環境,並安裝不同版本的redis
以滿足不同的編程需要
測試
單元測試
在 Python 裏我們有 unittest 這個模塊來幫助我們進行單元測試。
首先導入了 unittest 模塊,然後測試我們需要測試的函數。
測試用例是通過子類化 unittest.TestCase 創建的。
覆蓋測試率
測試覆蓋率是找到代碼庫未經測試的部分的簡單方法。它並不會告訴你的測試好不好。
項目結構
假設實驗項目名為factorial創建/home/shiyanlou/factorial
,將要創建的Python模塊取名為myfact,創建目錄/home/shiyanlou/factorial/myfact
。主代碼放在fact.py文件中,模塊的__init.py__文件,將設定目錄顯示的文件。
/home/shiyanlou/factorial/MANIFEST.in
文件,它用來在使用 sdist 命令的時候找出將成為項目源代碼壓縮包一部分的所有文件。
最終我們需要寫一個 /home/shiyanlou/factorial/setup.py
,用來創建源代碼壓縮包或安裝軟件。
要創建一個源文件發布版本,執行以下命令。
python3 setup.py sdist
我們能在 dist 目錄下看到一個 tar 壓縮包。執行下面的命令從源代碼安裝。
sudo python3 setup.py install
Flask框架基本使用
Flask 是一個 web 框架。也就是說 Flask 為你提供工具,庫和技術來允許你構建一個 web 應用程序。這個 web 應用程序可以是一些 web 頁面、博客、wiki、基於 web 的日歷應用或商業網站。
Flask 屬於微框架(micro-framework)這一類別,微架構通常是很小的不依賴於外部庫的框架。這既有優點也有缺點,優點是框架很輕量,更新時依賴少,並且專註安全方面的 bug,缺點是,你不得不自己做更多的工作,或通過添加插件增加自己的依賴列表。
Flask 的依賴如下:
- Werkzeug 一個 WSGI 工具包
- jinja2 模板引擎
WSGI
Web服務器網關接口(Python Web Server Gateway Interface,縮寫為WSGI)是為Python語言定義的Web服務器和Web應用程序或框架之間的一種簡單而通用的接口。自從WSGI被開發出來以後,許多其它語言中也出現了類似接口。
flask框架使用
- templates 文件夾是存放模板的地方,
- static 文件夾存放 web 應用所需的靜態文件(images, css, javascript)。
hello_flask.py 文件裏編寫如下代碼:
運行flask程序
了解了微框架、WSGI、模板引擎等概念,學習使用 Flask 做一個 web 應用,在這個 web 應用中,我們使用了模板。而用戶以正確的不同 URL訪問服務器時,服務器返回不同的網頁。
以上是這周在實驗樓學習的關於Python3的相關知識,但是因為時間有限,很多內容還有待進一步深入,很多內容掌握的也不是很牢固,需要在以後的學習實踐中不斷鞏固深入。
2018-2019-2 20189206 Python3學習