国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Python常用基礎(chǔ)語(yǔ)法知識(shí)點(diǎn)大全合集,看完這一篇文章就夠了

這篇具有很好參考價(jià)值的文章主要介紹了Python常用基礎(chǔ)語(yǔ)法知識(shí)點(diǎn)大全合集,看完這一篇文章就夠了。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

介紹

Python 是一門獨(dú)特的語(yǔ)言,快速瀏覽一下他的要點(diǎn):

  • 面向?qū)ο螅好恳粋€(gè)變量都是一個(gè)類,有其自己的屬性(attribute)與方法(method)。
  • 語(yǔ)法塊:用縮進(jìn)(四個(gè)空格)而不是分號(hào)、花括號(hào)等符號(hào)來(lái)標(biāo)記。因此,行首的空格不能隨意書寫。
  • 注釋:行內(nèi)用“#”號(hào),行間注釋寫在兩組連續(xù)三單引號(hào)之間:’’’
  • 續(xù)行:行尾輸入一個(gè)反斜杠加一個(gè)空格(’\ ‘),再換行。如果行尾語(yǔ)法明顯未完成(比如以逗號(hào)結(jié)尾),可以直接續(xù)行。
  • 打印與輸入: 函數(shù) print() 與 input(),注意 print() 的 sep 與 end 參數(shù)。
  • 變量:無(wú)需指定變量類型,也不需要提前聲明變量。

    • 刪除變量:del()
    • 復(fù)制變量:直接將變量a賦值給b,有時(shí)僅僅復(fù)制了一個(gè)“引用”。此后 b 與 a 的改動(dòng)仍會(huì)互相影響。必要時(shí)使用 a is b 來(lái)判斷是否同址。
  • 模塊:通過(guò) import pandas 的方式加載模塊(或者 import pandas as pd),并用形如 pandas.DataFrame(或 pd.DataFrame)的方式調(diào)用模塊內(nèi)的方法。也可以使用 from pandas import DataFrame 的方式,這樣在下文可以直接使用 DataFrame 作為調(diào)用名。
  • 幫助:配合使用 dir() 與 help() 命令;其中前者是輸出變量所有的成員。以及查閱 官網(wǎng)頁(yè)面。

變量復(fù)制的一個(gè)例子。

a = [1, 2]
b = a
print(id(a) - id(b))  # 地址差為 0,表示實(shí)質(zhì)是同址的
0
b.append(3)
print(a)  # 只改動(dòng)了 b,但 a 也跟著變動(dòng)了
[1, 2, 3]
a is b
True

使用切片來(lái)重新分配空間:

a is a[:]
False

數(shù)據(jù)結(jié)構(gòu)

Python 原生的數(shù)據(jù)結(jié)構(gòu)包括:

數(shù)字(num)

細(xì)分為整數(shù)(int)與浮點(diǎn)數(shù)(float)兩種。

  • 四則運(yùn)算:+, -,?, / ,乘方:?*
  • 整除: 5 // 2 = 2,取余:5 % 2 = 1
  • 自運(yùn)算: a += 1 (四則與乘方均可類似自運(yùn)算)
    以及一些細(xì)節(jié):
  • 運(yùn)算兩數(shù)中只要有一個(gè)浮點(diǎn)數(shù),結(jié)果就是浮點(diǎn)數(shù);
  • 整數(shù)相除,即使能除盡,結(jié)果也是浮點(diǎn)數(shù);
  • Python 內(nèi)部的機(jī)制解決了整數(shù)溢出的問(wèn)題,不用擔(dān)心。

布爾(bool)與邏輯

首字母大寫 True / False.

  • 邏輯運(yùn)算符:與 A and B,或 A or B,非 not A
  • 邏輯關(guān)系符:等于 ==, 不等于 !=. 其他不贅述。
  • 幾種邏輯判斷例子:
變量 x x = [] x = 0 x = 2
bool(x) False False True
if x: … False False True
if x is None: … False False False

序列(sequence)

序列主要包括字符串(str)、列表(list)與元祖(tuple)三類。

  • 序列索引規(guī)則:

    • 索引從0開始,到 N-1 結(jié)束。
    • 切片:切片的索引是左閉右開的。

      • seq[0:2](從 0 到 1)
      • seq[2:](從 2 到尾)
      • seq[:3] (從頭到 2)
      • seq[:](全部)
      • seq[:10:2](從頭到9,每?jī)蓚€(gè)取一個(gè))
      • seq[::2](全部,每?jī)蓚€(gè)取一個(gè))
    • 索引允許負(fù)數(shù):seq(-1) 與 seq(N - 1) 等同,seq(-3:-1)與 seq(N-3:N-1) 等同。
  • 序列通用函數(shù):

    • len():返回序列長(zhǎng)度。
    • +/* :加號(hào)用于連接兩個(gè)序列,乘號(hào)重復(fù)排列若干次再連接。
    • seq1 in seq2:如果 seq1 這個(gè)片段可以在 seq2 中被找到,返回 True.
    • index:在 seq1 in seq2 為 True 時(shí)使用,seq2.index(seq1) 表示 seq1 首次出現(xiàn)于 seq2 中的位置。
    • max()/min():返回序列中的最值。如果不是數(shù)字,則按 ASCII 碼順序返回。
    • cmp(seq1, seq2):比較大小。結(jié)果為負(fù),則表示 seq1 較小。

字符串(str)

寫于一對(duì)雙引號(hào)或單引號(hào)內(nèi)。用 str() 可以強(qiáng)制轉(zhuǎn)換為字符串。

  • 轉(zhuǎn)義:反斜杠。如果強(qiáng)制不解釋字符串,在左引號(hào)前加字母 r 即可:?r"c:\new".
  • 分割與連接:**.split()?與?**.join().

    s = " I love Python"  # 首位是空格
    lst = s.split(' ')
    lst1 = '-'.join(lst)
    
    print(lst, '\n', lst1)
    ['', 'I', 'love', 'Python'] 
     -I-love-Python
  • 緊切:strip()?去掉字符串首尾兩端的空格。方法?lstrip()/rstrip()?則只切除首端/尾端的空格。

    s.strip()
    'I love Python'
  • 大小寫轉(zhuǎn)換:如下幾個(gè)方法:

    • 首字母大寫:s.title()
    • 全大寫:s.upper()
    • 全小寫:s.lower()
    • 句首大寫:s.capitalize()
  • 格式化:字符串格式化是一種實(shí)用功能。通過(guò) .format() 成員函數(shù)完成。

    'I like {} and {}'.format('Python', 'you')
    'I like Python and you'
    '{0} + {2} = {1}'.format (10, 20, 'Python ')  # 按順序引用
    '10 + Python  = 20'
    '{0} * {1} = {0}'.format (10, 'Python ')  # 編號(hào)反復(fù)引用
    '10 * Python  = 10'

    格式化控制碼:

控制碼 含義 控制碼 含義
:s 字符串 :c 單個(gè)字符
:b/o/x/d 二、八、十六、十進(jìn)制數(shù) :e/f 科學(xué)計(jì)數(shù)法/浮點(diǎn)數(shù)

一些復(fù)雜控制的例子:

例子 含義 例子 含義
:.2f/:+.2f 兩位小數(shù)/帶符號(hào)兩位小數(shù) : .2f 正數(shù)前補(bǔ)空格的兩位小數(shù)
:, 逗號(hào)分隔符 :.2% 百分比兩位小數(shù)
:.2e 科學(xué)計(jì)數(shù)法兩位小數(shù) :^4d 總寬四位居中對(duì)齊
:>4d/<4d 總寬四位左/右對(duì)齊 :0>4d 總寬四位左側(cè)補(bǔ)零

舉例:

"{:0>7.2f} is an odd number".format(123.4)  # 總寬 7 位小數(shù)點(diǎn)后 2 位,左側(cè)補(bǔ)零
'0123.40 is an odd number'

其他實(shí)用的字符串函數(shù):

  • str.replace(old, new[, times]):將字符串中前 times 個(gè) old 子串替換為 new。Times 不指定時(shí)默認(rèn)替換全部。
  • str.isdigit():判斷字符串是否每一位都是數(shù)字,返回 True 或者 False。
    字符串中正則表達(dá)式的內(nèi)容參見本文附錄。

列表(list)

中括號(hào)式的結(jié)構(gòu)。list()?用于強(qiáng)制轉(zhuǎn)換類型。

lst = [1, 2, 3]
print(lst)
[1, 2, 3]
# 【反轉(zhuǎn)】:其中第二種方式會(huì)更改現(xiàn)有的列表
lst1 = list(reversed(lst))
lst.reverse()
print(lst1, lst)
[3, 2, 1] [3, 2, 1]
# 【追加】:元素 append(),另一個(gè)列表:extend()
lst.append(4)
print(lst)
[3, 2, 1, 4]
lst.extend(lst1)
print(lst)
[3, 2, 1, 4, 3, 2, 1]
# 【插入】:lst.insert(idx, obj) 會(huì)在 lst[idx] 處插入 obj,然后依次后移原有項(xiàng)
lst.insert(1, 100)
print(lst)
[3, 100, 2, 1, 4, 3, 2, 1]
# 【刪除】:lst.remove(obj) 會(huì)刪除首個(gè)匹配值,若無(wú)匹配會(huì)報(bào)錯(cuò);
#           lst.pop(idx) 會(huì)返回 lst[idx],并將其刪除。如果不指定 idx,默認(rèn)為列表尾
lst.remove(2)
print(lst)
[3, 100, 1, 4, 3, 2, 1]
tmp = lst.pop()
print(lst, "\n", tmp)
[3, 100, 1, 4, 3, 2] 
 1
# 【搜索】:使用序列通用函數(shù)即可。用 count(obj) 可以計(jì)算頻數(shù)。
# 【排序】:sort() 方法。如果指定 reverse 參數(shù),可降序排序。
lst.sort(reverse=True)
print(lst)
[100, 4, 3, 3, 2, 1]
# 【清空】:clear()
lst.clear()
print(lst)
[]

元組(tuple)

圓括號(hào)式的結(jié)構(gòu),是一種不可變序列。

a = (1, 'string ', [1 ,2])
print(a)
(1, 'string ', [1, 2])

Note: 定義一個(gè)空的元組用(),定義只有一個(gè)元組的元組,需要加,,否則就不是元組了,如下:

>>> tuple1 = ()
>>> type(tuple1)
<type 'tuple'>
>>> tuple2 = (1)
>>> type(tuple2)
<type 'int'>
>>> tuple3 = (1,)
>>> type(tuple3)
<type 'tuple'>

字典(dict)

字典是一種類哈希表的數(shù)據(jù)結(jié)構(gòu),內(nèi)部無(wú)序,通過(guò)鍵值對(duì)(key: value)的形式存儲(chǔ)數(shù)據(jù)。幾種字典初始化的方式:

# 小字典直接賦值
d1 = {"name": "wklchris", "gender": "male"}
# 利用字典增加鍵值對(duì)的方法
d2 = {}
d2['name'] = 'wklchris'
# 一個(gè)值賦給多個(gè)鍵
d3 = {}.fromkeys(("name", "gender"), "NA")
# 強(qiáng)制格式轉(zhuǎn)換
d4 = dict(name="wklchris", gender="male")

print(d1, d2, d3, d4, sep="\n")
{'name': 'wklchris', 'gender': 'male'}
{'name': 'wklchris'}
{'name': 'NA', 'gender': 'NA'}
{'name': 'wklchris', 'gender': 'male'}

字典的操作方法:

len(d1)
2
# 【復(fù)制】:
dd = d1.copy()
dd is d1
False
# 【查找鍵名稱】:
"name" in dd
True
# 【刪除鍵值對(duì)】
del(dd["name"])
# 【get】
dd.get("name", "Nothing")  # 如果鍵不存在,返回“Nothing”
'Nothing'
# 【setdefault】
dd.setdefault("name", "wklchris")  # 如果鍵不存在,就新建該鍵,并賦值
'wklchris'
print(dd)
{'name': 'wklchris', 'gender': 'male'}
# 【輸出鍵值】:
list(dd.items())
[('name', 'wklchris'), ('gender', 'male')]
list(dd.keys())
['name', 'gender']
list(dd.values())
['wklchris', 'male']
# 【彈出鍵值對(duì)】:pop(key) / popitem(key)
# 其中,后者會(huì)隨機(jī)彈出一個(gè)鍵值對(duì)
tmp = dd.pop("gender")
print(dd, tmp)
{'name': 'wklchris'} male
# 【更新】:update(ref_dict) 以 ref_dict 為準(zhǔn),更新當(dāng)前字典
d4 = {"name": "Test", "Age": 3}
dd.update(d4)
print(dd)
{'name': 'Test', 'Age': 3}

集合(set)

本文只討論可變集合,關(guān)于不可變集合的內(nèi)容,參考 help(frozenset)。

集合是一種無(wú)序的數(shù)據(jù)存儲(chǔ)方式,且內(nèi)部元素具有唯一性。集合與字典一樣都可以用花括號(hào)的形式創(chuàng)立。但在書寫 a={} 時(shí),Python 會(huì)將其識(shí)別為字典類型。

  • 增添:add() / update()
  • 刪除:remove() / discard(),區(qū)別在于后者搜索無(wú)結(jié)果會(huì)報(bào)錯(cuò)。
  • 從屬:a.issubset(b) 集合 a 是否是 b 的子集;a.issuperset(b) 集合 a 是否是 b 的父集。a == b 兩集合是否全等。
  • 集合運(yùn)算:集合運(yùn)算不會(huì)改變參與運(yùn)算的集合本身。

    • 并集: a | b 或者 a.union(b)
    • 交集: a & b 或者 a.intersection(b)
    • 補(bǔ)集: a - b 或者 a.difference(b)
      注意:在字符串強(qiáng)制轉(zhuǎn)換為集合時(shí),必要時(shí)使用中括號(hào)先轉(zhuǎn)為列表(否則字符串會(huì)被拆分為單個(gè)字符后再進(jìn)行轉(zhuǎn)換)。例如:

      ss = {"a", "b", "c"}
      ss | set("de")
      {'a', 'b', 'c', 'd', 'e'}
      ss | set(["de"])
      {'a', 'b', 'c', 'de'}

基本語(yǔ)句

同大多數(shù)程序語(yǔ)言一樣,Python 擁有?if, for, while語(yǔ)句。什么?switch?語(yǔ)句?使用字典就好。

if 語(yǔ)句與三元操作

在 Python 中,else if?被縮寫為單個(gè)關(guān)鍵詞?elif.

if 1.0 > 1:
    a = 1
elif 1.0 < 1:
    a = 2
else:
    a = 3
    
a
3

值得一提的是,Python 中的 if 語(yǔ)句支持鏈?zhǔn)奖容^,形如?a < x < b, a < x >= b?等:

a = 0
if 1 < 2 > 1.5:
    a = 1
a
1

三元操作實(shí)質(zhì)是高度簡(jiǎn)化的 if 環(huán)境,形如?X = a if flag else b

a = 1 if 2 < 1 else 2
a
2

for 語(yǔ)句

Python 的循環(huán)語(yǔ)句中,像其他語(yǔ)言一樣,有?break(跳出循環(huán)體) 與?continue(循環(huán)步進(jìn)) 關(guān)鍵詞可以使用。

for 語(yǔ)句借助關(guān)鍵詞 in 使用:(函數(shù)?range(N, M=0, s=1)?是一個(gè)生成等差數(shù)列的函數(shù),位于左閉右開區(qū)間[M,N)上且公差為 s)。

for i in range(3):
    print(i)
0
1
2

注意到字典的 d.items(), d.keys(), d.values() 命令也常常用于 for 語(yǔ)句:

d = {"a": 1, "b": 2, "c": 3}
for k, v in d.items():
    print(k, v)
b 2
c 3
a 1

以上等價(jià)于:

for k in d.keys():
    print(k, d[k])
b 2
c 3
a 1

Python 中的?for?語(yǔ)句可選?else?語(yǔ)法塊,表示?for?語(yǔ)句正常結(jié)束后執(zhí)行的內(nèi)容(中途?break?不屬于正常結(jié)束)。這對(duì)于處理一些 break 操作很有幫助。例如:

a = 0
flag = 0
for i in range(5):
    if i > 2:
        flag = 1
        break
if flag == 1:
    a = 1
a
1

這在 Python 中顯得太復(fù)雜了,直接使用?for…else…即可:

a = 1
for i in range(5):
    if i > 1:
        break
else:
    a = 0
a
1

while 語(yǔ)句

while 語(yǔ)句的?else?語(yǔ)法塊,指明了退出 while 循環(huán)后立刻執(zhí)行的內(nèi)容;它不是必需的。

如果你想要將 while 語(yǔ)句內(nèi)部的參數(shù)傳出(比如下例的計(jì)數(shù)器終值),這是一個(gè)不錯(cuò)的方案。

count = 1
while count < 5:
    a = count
    count *= 2
else:
    b = count

print(a, b)
4 8

列表解析

列表解析是一種創(chuàng)建列表的高度縮寫方式:

lst = [x ** 2 for x in range(4)]
lst
[0, 1, 4, 9]

也可以配合 if 語(yǔ)句:

lst = [x ** 2 for x in range(4) if x > 0]
lst
[1, 4, 9]

類似的,也有字典解析,以及下文會(huì)介紹的生成器,也有生成器解析(把外圍的括號(hào)換成圓括號(hào)即可):

{n: n ** 2 for n in range(3)}
{0: 0, 1: 1, 2: 4}

函數(shù)

本節(jié)介紹 Python 函數(shù)的基礎(chǔ)特點(diǎn),以及一些實(shí)用函數(shù)。

函數(shù)定義與判斷

使用?def?關(guān)鍵字。三連雙引號(hào)間的內(nèi)容被視為函數(shù)的幫助字符串,可以通過(guò)?help()?命令查看。

def func(a, b=0):
    """
    This is a function that can meow.
    """
    return " ".join(["meow"] * (a + b))

調(diào)用函數(shù):

func(2)  # 單參數(shù),僅 a 
'meow meow'
func(2, 3)  # 雙參數(shù), a 與 b 都被傳入
'meow meow meow meow meow'
help(func)
Help on function func in module __main__:

func(a, b=0)
    This is a function that can meow.

通過(guò)?callable()?可以判斷一個(gè)對(duì)象是否是一個(gè)可調(diào)用的函數(shù):

callable(func)
True

不定參函數(shù)

利用序列(或元組)與字典,向函數(shù)傳參。前者在傳入時(shí)需要加上一個(gè)星號(hào),后者需要兩個(gè)。

lst = [1, 3, 4]
d = {"a": 2, "b": 3, "c": 5}
print("{}+{}={}".format(*lst), "{a}+={c}".format(**d))
1+3=4 2+3=5

zip 函數(shù)

zip() 函數(shù)的作用是“合并”多個(gè)列表為一個(gè)。其返回值是一個(gè)列表,列表內(nèi)的元素類型是元組。如果待合并的列表長(zhǎng)度不同,以最短的為準(zhǔn)。

a = [1, 2, 3, 4]
b = [5 ,6, 7]
c = "abcd"
list(zip(a, b, c))
[(1, 5, 'a'), (2, 6, 'b'), (3, 7, 'c')]

它比較常用于交換字典的鍵與值:

dict(zip(d.values(), d.keys()))
{2: 'a', 3: 'b', 5: 'c'}

lambda 函數(shù)

一種匿名函數(shù)的聲明方式。如果你使用過(guò)?MATLAB,你可能熟悉這一類概念。

func = lambda x, y: x + y
func(2, 5)
7

map 函數(shù)

map()?能夠?qū)魅氲男蛄羞M(jìn)行依次操作,并將結(jié)果返回為一個(gè)可轉(zhuǎn)換為列表的?map?對(duì)象。通常列表解析(或生成器解析)可以實(shí)現(xiàn)與其同樣的工作。

lst = list(map(lambda x: x + 1, range (5)))
print(lst)
[1, 2, 3, 4, 5]
f = lambda x: x + 1
[f(x) for x in range(5)]
[1, 2, 3, 4, 5]

filter 函數(shù)

給定序列,對(duì)于滿足某規(guī)則的部分(即 True),予以返回。

list(filter(lambda x: x > 0, range(-3, 3)))
[1, 2]

reduce 函數(shù)

該函數(shù)在 Python 2 中是可以直接調(diào)用的,但在 Python 3 中需要從?functools?模塊進(jìn)行調(diào)用。

from functools import reduce
reduce(lambda x, y: x + y, range (5))  # 0+1+2+3+4
10

enumerate 函數(shù)

它允許你像 d.items() 那樣,用類似的方式操作列表:

a = [1, 3, 5]
for i, v in enumerate(a):
    print("lst[{}] = {}".format(i, v))

lst[0] = 1
lst[1] = 3
lst[2] = 5

裝飾器:算子

裝飾器是函數(shù)的函數(shù)——傳入的參數(shù)是一個(gè)函數(shù),返回的值也是一個(gè)函數(shù)。相當(dāng)于一個(gè)函數(shù)集到另一個(gè)函數(shù)集的映射,可以理解為數(shù)學(xué)意義上的算子。

首先來(lái)看一個(gè)簡(jiǎn)單的例子:函數(shù)可以被賦值給一個(gè)變量。

def pyrint(data="Python"):
    return data.upper()

f = pyrint
f()
'PYTHON'

還可以通過(guò)?__name__?來(lái)得到當(dāng)前函數(shù)的名稱:

f.__name__
'pyrint'

那什么時(shí)候需要裝飾器呢?比如在函數(shù)需要被重用、但又不能直接改寫?def?的場(chǎng)合(在維護(hù)中應(yīng)該不少見吧?。?。例如,我們希望在返回值之前,把函數(shù)名也打印出來(lái):

def showname(func):
    def subfunc(*args, **kwarg):
        print("FUNCTION {} called.".format(func.__name__))
        return func(*args, **kwarg)
    return subfunc

這樣如果我們通過(guò)?showname(pyrint)?這種形式,就能夠在?pyrint?函數(shù)被調(diào)用之前,額外打印一行內(nèi)容。

想要改動(dòng)該函數(shù),不需要改動(dòng) def 語(yǔ)句以下的內(nèi)容,只需要用?@showname?命令來(lái)應(yīng)用這個(gè)裝飾器:

@showname
def pyrint(data="Python"):
    return data.upper()
pyrint()
FUNCTION pyrint called.

'PYTHON'

如果裝飾器需要傳遞參數(shù),那么,需要在定義時(shí),外層再嵌套一個(gè)函數(shù):

def showname(num=1):
    def decorator(func):
        def subfunc(*args, **kwarg):
            print("Call time: {}. FUNCTION {} called.".format(num, func.__name__))
            return func(*args, **kwarg)
        return subfunc
    return decorator

@showname(2)
def pyrint(data="Python"):
    return data.upper()

pyrint()
Call time: 2. FUNCTION pyrint called.

'PYTHON'

不過(guò)裝飾器被應(yīng)用于函數(shù)定義之前時(shí),函數(shù)的?__name__?屬性會(huì)改變。比如上例:

pyrint.__name__
'subfunc'
使用模塊 functools 來(lái)解決這一問(wèn)題:

import functools

def showname(num=1):
    def decorator(func):
        @functools.wraps(func)  # 加上這一行
        def subfunc(*args, **kwarg):
            print("Call time: {}. FUNCTION {} called.".format(num, func.__name__))
            return func(*args, **kwarg)
        return subfunc
    return decorator

@showname(2)
def pyrint(data="Python"):
    return data.upper()

pyrint.__name__
'pyrint'

迭代器 [itertools]

迭代器與生成器在內(nèi)存優(yōu)化上很有意義。

迭代器

迭代器最顯著的特征是擁有?__iter__()?和?__next__()?方法;它像一個(gè)鏈表。如果它指向末尾,那么再次執(zhí)行?__next__()?時(shí)會(huì)報(bào)錯(cuò)。一個(gè)例子:

a = [1, 2, 3]
b = iter(a)
print(b.__next__(), b.__next__())  # 或者使用 next(b)
1 2

實(shí)際上,Python 3 內(nèi)置了一個(gè)?itertools?的庫(kù),里面有諸如?cycle?和?count?等適用于迭代器的函數(shù):

import itertools

# count: 給定首項(xiàng)與公差的無(wú)窮等差數(shù)列
p = itertools.count(start = 1, step = 0.5)
print(p.__next__(), p.__next__())

# cycle: 周期循環(huán)的無(wú)窮序列
p = itertools.cycle(list("AB"))
print(next(p), next(p), next(p))

# islice: 從無(wú)窮序列中切片
p = itertools.cycle(list("AB"))
print(list(itertools.islice(p, 0, 4)))
1 1.5
A B A
['A', 'B', 'A', 'B']

請(qǐng)時(shí)刻注意當(dāng)前指向的迭代器位置——失之毫厘,謬以千里。

生成器

生成器是迭代器的一種,其實(shí)質(zhì)是定義中含有 yield 關(guān)鍵詞的函數(shù)。它沒有 return() 語(yǔ)句。

生成器可以直接使用類似列表解析的方式,稱為生成器解析。例如:(i for i in range(10)。

def Fib(N):  # 斐波那契數(shù)列
    n, former, later = 0, 0, 1
    while n < N:
        yield later
        former, later = later, later + former
        n += 1

list(Fib(5))
[1, 1, 2, 3, 5]

上例與普通的寫法看上去差別不大,但實(shí)際上可以將 while 語(yǔ)句改寫為?while True,刪除變量 n,在外部借助 itertools 的?islice?函數(shù)來(lái)截取。這在函數(shù)定義時(shí)對(duì)代碼的壓縮是顯然的。

def iterFib():
    former, later = 0, 1
    while True:
        yield later
        former, later = later, later + former

list(itertools.islice(iterFib(), 0, 5))
[1, 1, 2, 3, 5]

錯(cuò)誤:try()?語(yǔ)句

常見的錯(cuò)誤有以下幾種:

  • ZeroDivisionError: 除數(shù)為 0.
  • SyntaxError:語(yǔ)法錯(cuò)誤。
  • IndexError:索引超界。
  • KeyError:字典鍵不存在。
  • IOError:讀寫錯(cuò)誤。
    try() 語(yǔ)句的常見寫法:

    try:
      a = 1 
    except ZeroDivisionError as e:
      print(e)
      exit()
    else:  # 如果無(wú)錯(cuò)誤,執(zhí)行
      print(a)
    finally:  # 不管有無(wú)錯(cuò)誤均執(zhí)行
      print("-- End --")
    1
    -- End --

    其中,else?與?finally?語(yǔ)句都不是必需的。如果不想輸出錯(cuò)誤信息、或不能預(yù)先判斷可能的錯(cuò)誤類型,可以使用僅含 exit() 語(yǔ)句的?except?塊。

多個(gè) except 塊

一個(gè) try 語(yǔ)法塊是可以跟著多個(gè)?except?的;如果靠前的 except 捕獲了錯(cuò)誤,之后的就不會(huì)運(yùn)行。 這也就是說(shuō),如果錯(cuò)誤之間有繼承關(guān)系時(shí),子錯(cuò)誤需要放在父錯(cuò)誤之前嘗試 except,否則子錯(cuò)誤永遠(yuǎn)也不可能被捕獲。

比如上一節(jié)的例子中,ZeroDivisionError?是?ArithmeticError?下的子錯(cuò)誤,而?ArithmeticError?又是 Exception 下的子錯(cuò)誤(當(dāng)不清楚錯(cuò)誤的類型時(shí),Exception 可以捕獲絕大多數(shù)錯(cuò)誤)。關(guān)于錯(cuò)誤的繼承關(guān)系,參考:Python - Exception Hierarchy 官方頁(yè)面。

一個(gè)例子:

try:
    a = 1 / 0
except Exception:
    print("Exception")
    exit()
except ZeroDivisionError:
    print("ZeroDivisionError")
    exit()
else:
    print("No error.")
finally:
    print("-- End --")
輸出 Exception 與 – End –。

錯(cuò)誤的捕獲

錯(cuò)誤在很多地方都可能發(fā)生,那是否需要在可能的地方都加上 try 語(yǔ)句呢?當(dāng)然不是。建議只在主代碼中加入 try 語(yǔ)句,因?yàn)?Python 會(huì)自動(dòng)跟蹤到錯(cuò)誤產(chǎn)生的源頭何在。

錯(cuò)誤的拋出及上拋

有時(shí)候我們想人為拋出一個(gè)錯(cuò)誤,這是使用?raise?即可:

# raise TypeError("Wrong type.")

如果在函數(shù)中沒有處理錯(cuò)誤的語(yǔ)句,可能在捕獲錯(cuò)誤后將其上拋。記住,捕獲錯(cuò)誤只是為了記錄錯(cuò)誤的產(chǎn)生,并不意味者必須原地解決錯(cuò)誤。

def makeerror(n):
    if n == 0:
        raise ValueError("Divided by zero.")
    return 1 / n

def callerror():
    try:
        makeerror(0)
    except ValueError as e:
        print("ValueError detected.")
        raise

# 輸出 "ValueError detected." 并打印錯(cuò)誤日志
# callerror()

上面的?raise?命令沒有緊跟任何參數(shù),表示將錯(cuò)誤原樣上拋。你也可以手動(dòng)指定上拋的錯(cuò)誤類型,并不需要與原錯(cuò)誤類型一致。甚至你可以定義一個(gè)錯(cuò)誤(繼承某一錯(cuò)誤類):

class MyError(ValueError):
    print("This is MyError.")

# raise MyError
This is MyError.

文件讀寫

open() 函數(shù)用于文件的讀寫操作。一般我們會(huì)在操作文件時(shí),引入 os 模塊(os 模塊的用法參考“常用模塊”一節(jié)的內(nèi)容)。

import os

open()?函數(shù)常常配合?with?語(yǔ)法塊進(jìn)行使用,它會(huì)在語(yǔ)法塊結(jié)束時(shí)自動(dòng)關(guān)閉文件。該函數(shù):

open(file, mode="r", encoding=None)

第一參數(shù)是包含文件名的路徑(傳入基于當(dāng)前目錄的相對(duì)路徑,傳入或者絕對(duì)路徑),mode 參數(shù)是讀寫操作方式;encoding?是編碼類型,一般取”utf8”。其中,讀寫操作方式常用的有:

參數(shù) 含義
“r” (默認(rèn))讀。
“w” 寫。該模式會(huì)覆蓋原有內(nèi)容;如文件不存在,會(huì)自動(dòng)新建。
“x” 創(chuàng)建新文件并寫入。
“a” 在已有文件的尾部追加。

一般讀寫操作:read() / readlines()

函數(shù)?read()?將整個(gè)文件讀為一個(gè)字符串,來(lái)看一個(gè)例子:

datapath = os.path.join(os.getcwd(), "data", "iris.data.csv")
with open(datapath, "r", encoding="utf8") as f:
    rawtext = f.read()

rawtext[:200]
'5.1,3.5,1.4,0.2,Iris-setosa\n4.9,3.0,1.4,0.2,Iris-setosa\n4.7,3.2,1.3,0.2,Iris-setosa\n4.6,3.1,1.5,0.2,Iris-setosa\n5.0,3.6,1.4,0.2,Iris-setosa\n5.4,3.9,1.7,0.4,Iris-setosa\n4.6,3.4,1.4,0.3,Iris-setosa\n5.0,'

函數(shù)?readlines()?將整個(gè)文件讀為一個(gè)列表,文件的每一行對(duì)應(yīng)列表的一個(gè)元素。

with open(datapath, "r", encoding="utf8") as f:
    rawtext = f.readlines()

rawtext[:3]
['5.1,3.5,1.4,0.2,Iris-setosa\n',
 '4.9,3.0,1.4,0.2,Iris-setosa\n',
 '4.7,3.2,1.3,0.2,Iris-setosa\n']

上述的?readlines()?函數(shù)實(shí)質(zhì)等同于列表解析:

with open(datapath, "r", encoding="utf8") as f:
    rawtext = [line for line in f]

rawtext[:3]
['5.1,3.5,1.4,0.2,Iris-setosa\n',
 '4.9,3.0,1.4,0.2,Iris-setosa\n',
 '4.7,3.2,1.3,0.2,Iris-setosa\n']

文件寫入,使用?write()?函數(shù)。一個(gè)簡(jiǎn)單的例子:

with open(datapath, "w") as f:
   f.write("Sometimes naive.")

大文件讀取:readline()

如果文件比較大,使用?read()/readlines()?函數(shù)直接讀入可能會(huì)占用太多內(nèi)存。推薦使用函數(shù)?readline(),一種迭代器式的讀取方法。

with open(datapath, "r", encoding="utf8") as f:
    print(f.readline().strip())
    print(f.readline().strip())
5.1,3.5,1.4,0.2,Iris-setosa
4.9,3.0,1.4,0.2,Iris-setosa

你會(huì)發(fā)現(xiàn)兩次結(jié)果是不同的,這是因?yàn)榈鲀?nèi)部的“指針”向后移動(dòng)了。

怎樣獲取 / 移動(dòng)“指針”的位置呢?使用 tell() / seek() 命令。

with open(datapath, "r", encoding="utf8") as f:
    print(f.tell(), f.readline().strip())
    print(f.tell(), f.readline().strip())
    f.seek(0)  # 回到文件頭
    print(f.tell(), f.readline().strip())
0 5.1,3.5,1.4,0.2,Iris-setosa
28 4.9,3.0,1.4,0.2,Iris-setosa
0 5.1,3.5,1.4,0.2,Iris-setosa

類的成員包括屬性(attribute)與方法(method)兩種。例子:

class MyClass:
    """
    This is a class that can meow!
    """
    animal = "cat"  # An attribute
    def talk(self):  # A method
        return "Meow"

# An instance of the class
a = MyClass()
print(a.animal, a.talk())
cat Meow

上例中的?self?表示類的實(shí)例,所有類內(nèi)部的方法都需要把該參數(shù)放在首位(你也不可不用 self 而使用 this 等,但是?self?是慣例)。例如,self.animal?就表示了實(shí)例的 animal 屬性。這與 C# 等語(yǔ)言中的“this.animal”是類似的。

下例證明了?self?代表的實(shí)質(zhì)是類的實(shí)例,而不是類本身。

class EgClass:
    def __init__(self):
        print(self)  # 實(shí)例,有對(duì)應(yīng)地址
        print(self.__class__)  # 類

a = EgClass()
<__main__.EgClass object at 0x000002531C0AF860>
<class '__main__.EgClass'>

構(gòu)造函數(shù):__init__()

類的構(gòu)造函數(shù)是?__init__()?(左右均為雙下劃線),用于初始化實(shí)例。在聲明實(shí)例時(shí),該函數(shù)自動(dòng)被調(diào)用。

class MyClass2:
    def __init__(self, animal="cat"):
        self.animal = animal

a = MyClass2("dog")
a.animal
'dog'

封裝

類的重要特性是封裝性,即部分變量只能在其內(nèi)部修改或訪問(wèn),不能從類的外部進(jìn)行處理。Python 中的封裝非常簡(jiǎn)單,只要把屬性或方法的名稱前綴設(shè)置為雙下劃線即可。

由此可見,構(gòu)造函數(shù)?__init__()?是最基本的一個(gè)私有方法。一個(gè)例子:

class MyClass3:
    def __init__(self, animal="cat"):
        self.__animal = animal
        self.__foo()
    def __foo(self):
        self.__animal = "rabbit"
    def show(self):
        print(self.__animal)

a = MyClass3("dog")
a.show()
rabbit

如果想直接調(diào)用?__foo() 或者 __animal,都會(huì)被禁止,產(chǎn)生?AttributeError。

# a.__animal  # AttributeError

要注意,前后均添加了雙下劃線的屬性,如?name?,表示特殊屬性而不是私有屬性,是可以從外部訪問(wèn)的。

繼承

下面是一個(gè)著名的貓與狗的例子;類 Cat 與 Dog 都繼承自 Animal,同時(shí)也都重載了方法 talk()。

class Animal:
    def talk(self):
        pass # 表示定義留空

class Cat(Animal): # 從Animal 繼承
    def talk(self): # 重寫talk()
        print('Meow')

class Dog(Animal):
    def talk(self):
        print('Woof')

a, b = Cat(), Dog()
a.talk() # 'Meow'
b.talk() # 'Woof'
Meow
Woof

通過(guò)?isinstance()?函數(shù)可以判斷一個(gè)對(duì)象是否是某個(gè)類(或其子類)的實(shí)例:

print(isinstance(a, Cat), isinstance(a, Animal))
True True
或者:

type(a).__name__
'Cat'

當(dāng)然,類也可以多繼承。寫在左側(cè)的類的屬性與方法,在繼承時(shí)會(huì)被優(yōu)先采用。例如:

class Pet:
    def talk(self):
        print("Pet")

class Cat2(Pet, Cat):
    pass

a = Cat2()
a.talk()
Pet

@property 裝飾器

裝飾器?@property?可以被用于限制類屬性的讀寫行為。比如,一個(gè)普通的類,如果想封裝一個(gè)屬性,卻允許從外部讀取它的值,一般我們用?getter?函數(shù)實(shí)現(xiàn):

class Person:
    def __init__(self):
        self.__name = "Py"
    def get_name(self):
        return self.__name
a = Person()
a.get_name()
'Py'

不得不說(shuō)這實(shí)在是麻煩了,代碼里一堆 get 函數(shù)滿天飛并不令人愉快。而且還不能忘記它是一個(gè)函數(shù),需要在尾部加上括號(hào)。

裝飾器?@property?可以將一個(gè)方法偽裝成同名的屬性,因此裝飾了?getter?函數(shù)后,調(diào)用時(shí)就不用加上尾部的括號(hào)了:

class Person:
    def __init__(self):
        self.__name = "Py"
        
    @property
    def name(self):
        return self.__name
a = Person()
a.name
'Py'

而且,如果你想從外部修改該屬性的值,會(huì)產(chǎn)生錯(cuò)誤:

a.name = 1
---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-97-8c607f2aa25b> in <module>()
----> 1 a.name = 1


AttributeError: can't set attribute

但同時(shí),我們也可以指定其 setter 函數(shù)(該裝飾器 @age.setter 在用 @property 裝飾 age 方法后會(huì)自動(dòng)生成),讓屬性修改成為可能,甚至附加修改條件:

class Person:
    def __init__(self):
        self.__age = 20
        
    @property
    def age(self):
        return self.__age
    
    @age.setter
    def age(self, value):
        if not isinstance(value, int):
            raise ValueError("Age should be an integer.")
        else:
            self.__age = value
a = Person()
a.age = 30
a.age
30

不傳入整數(shù)會(huì)報(bào)錯(cuò):

a.age = 0.5
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-100-001bfa8fe26b> in <module>()
----> 1 a.age = 0.5


<ipython-input-98-83364d5faa13> in age(self, value)
     10     def age(self, value):
     11         if not isinstance(value, int):
---> 12             raise ValueError("Age should be an integer.")
     13         else:
     14             self.__age = value


ValueError: Age should be an integer.

類的特殊屬性與方法

屬性?__dict__

首先是?__dict__屬性,用于查看類的屬性與方法,返回一個(gè)字典。

a = MyClass()
MyClass.__dict__
mappingproxy({'__dict__': <attribute '__dict__' of 'MyClass' objects>,
              '__doc__': '\n    This is a class that can meow!\n    ',
              '__module__': '__main__',
              '__weakref__': <attribute '__weakref__' of 'MyClass' objects>,
              'animal': 'cat',
              'talk': <function __main__.MyClass.talk>})

需要注意的是,此時(shí)實(shí)例 a 的屬性沒有被更改過(guò),實(shí)例的?dict?是一個(gè)空字典:

print(a.__dict__, a.animal)
{} cat

類的?__dict__?方法下的同名鍵,與實(shí)例具有相同值。

MyClass.__dict__["animal"]
'cat'

一旦被從外部更改,實(shí)例 a 的?dict?字典就不再為空。

a.animal = "dog"
print(a.__dict__, a.animal)
{'animal': 'dog'} dog

屬性?__slots__

從上面可以看到,非私有的類屬性可以從外部更改值,而且屬性還能直接從外部增加。__slots__ 屬性的作用就在于使類的屬性不能從外部進(jìn)行更改、追加。它能夠限制屬性濫用,并在優(yōu)化內(nèi)存上也有意義。

class MySlotClass():
    __slots__ = ("meow", "woof")
    def __init__(self):
        self.meow = "Meow"
        self.woof = "Woof"
    
a = MySlotClass()
MySlotClass.__dict__
mappingproxy({'__doc__': None,
              '__init__': <function __main__.MySlotClass.__init__>,
              '__module__': '__main__',
              '__slots__': ('meow', 'woof'),
              'meow': <member 'meow' of 'MySlotClass' objects>,
              'woof': <member 'woof' of 'MySlotClass' objects>})

此時(shí),如果使用?a.__dict__,結(jié)果不會(huì)返回空字典,而是會(huì)報(bào)錯(cuò)。

運(yùn)算符重載

特別地,Python 提供了運(yùn)算符重載的功能。常用的對(duì)應(yīng)如下(參考 官方頁(yè)面):

方法 含義 應(yīng)用
一元運(yùn)算符
len?長(zhǎng)度 len(a)
bool?邏輯值 bool(a)
neg?取負(fù)值 -a
str?/?repr?字符串形式 repr(a) / str(a), print(a)
二元運(yùn)算符
add?加 a + b, a += b
sub?減 a - b, a -= b
mul?乘 a?b, a?= b
div?除 a / b, a /= b
pow?乘方 a?b, a?= b
radd?左加 … + a
二元關(guān)系符
lt?/?le?小于 / 小于等于 a < b, a <= b
gt?/?ge?大于 / 大于等于 a > b, a >= b
eq?/?ne?等于 / 不等于 a == b, a != b
比如下例中,對(duì)多個(gè)運(yùn)算進(jìn)行了重載,完成了二維向量在加減法上與向量、與數(shù)運(yùn)算的基本定義。

class Vector:
    def __init__(self, a, b):
        self.a = a
        self.b = b
   
    def __add__(self, another):
        if isinstance(another, Vector):
            c, d = another.a, another.b
        else:
            c, d = another, another
        return Vector(self.a + c, self.b + d)
    
    def __radd__(self, another):
        return self.__add__(another)
    
    def __neg__(self):
        return Vector(-self.a, -self.b)
    
    def __sub__(self, another):
        return self.__add__(-another)
    
    def __str__(self):
        return "Vector({},{})".format(self.a, self.b)

v1 = Vector(0,3)
v2 = Vector(5,-2)
print(v1 - 1, -v2, v1 + v2, v1 - v2)
Vector(-1,2) Vector(-5,2) Vector(5,1) Vector(-5,5)

其中,__repr__()?與?__str__()?的主要區(qū)別在于,前者在交互式步驟中顯示結(jié)果,后者在 print 函數(shù)中顯示結(jié)果。

例如上例,如果直接輸入 v1,不會(huì)以 “Vector(0,3)”的形式顯示。

v1  # 在類中附加定義: __repr__ = __str__ 即可解決問(wèn)題。
<__main__.Vector at 0x2531c129c88>

迭代行為

在類中也能定義迭代行為,需要 __iter__() 與 __next__() 方法。

# 該例改編自官方文檔
class MyClass4:
    def __init__(self, lst):
        self.data = lst
        self.__index = len(lst)
    def __iter__(self):
        return self
    def __next__(self):
        if self.__index == 0:
            raise StopIteration
        self.__index -= 1
        return self.data[self.__index]

a = MyClass4("Meow")
for char in a:
    print(char)
w
o
e
M

常用模塊

下面介紹幾個(gè)常用的 Python 標(biāo)準(zhǔn)模塊(即隨 Python 安裝的模塊)。更多的第三方模塊,例如 NumPy, pandas, matplotlib,可以參考本系列博文的其他文章。

os 模塊

這個(gè)模塊應(yīng)該是 Python 自帶模塊中使用率最高的一個(gè)了。一些例子:

# import os
#
# ----- 文件操作 -----
# os.rename("old.py", "new.py")  # 重命名
# os.remove("a.py")  # 刪除
# os.stat("b.py")  # 查看文件屬性
#
# ----- 路徑操作 -----
# os.getcwd()  # 獲取當(dāng)前目錄
# os.chdir(r"d:\list")  # 更改當(dāng)前目錄為
# os.chdir(os.pardir)  # 返回上一級(jí)目錄
# os.mkdir('newfolder ')  # 在當(dāng)前目錄新建一個(gè)文件夾
# os.listdir('c:\list')  # 列出文件夾下所有文件的列表
# os.removedirs('thefolder ')  # 刪除空文件夾
# os.path.isfile/ispath("f")  # 檢查路徑是文件或是目錄
# os.path.exists("f")  # 檢查路徑是否存在
# 
# ----- 操作平臺(tái)相關(guān) -----
# os.sep  # 當(dāng)前操作系統(tǒng)的路徑分隔符
# os.linesep  # 當(dāng)前操作系統(tǒng)的換行符
# os.path.join(r"c:\abc", "d")  # 連接字串成為路徑

sys 模塊

一般我很少用到這個(gè)模塊??赡苡羞@么幾個(gè)命令會(huì)用到:

  • sys.argv:能夠傳遞從命令行接受的參數(shù)到代碼內(nèi)。
  • sys.platform:當(dāng)前操作系統(tǒng)平臺(tái)。
  • sys.exit():無(wú)參數(shù)時(shí)拋出 SystemExit 錯(cuò)誤并退出;有參數(shù)時(shí)會(huì)在退出前輸出對(duì)應(yīng)的字符串到屏幕。

    import sys
    sys.platform
    'win32'

    一個(gè)?sys.argv?的例子:

    sys.argv
    ['e:\\python\\lib\\site-packages\\ipykernel_launcher.py',
     '-f',
     'C:\\Users\\wklchris\\AppData\\Roaming\\jupyter\\runtime\\kernel-3724c4c9-2130-485d-b388-7a84379fd043.json']

    以上不是典型的例子,因?yàn)椴⒉皇窃诿钚邢逻\(yùn)行的。命令行下通常有如下格式:

    python test.py hello

    此時(shí),sys.argv[0] = test.py,sys.argv[1] = hello.

re 模塊:正則表達(dá)式

參考本文附錄。

其他模塊

  • collection 模塊:

    • 提供了一種雙端列表 deque,可以用 appendleft, extendleft, popleft 等方法從 deque 的左側(cè)(也就是lst[0])進(jìn)行操作。注意,deque 的更新操作比 list 更快,但讀取操作比 list 慢。
    • 提供了一種缺省字典defaultdict,可以直接操作鍵值(即使這個(gè)鍵先前未定義);首次操作時(shí)會(huì)賦一個(gè)合理的初值,比如首次調(diào)用 d["a"] += 1 而字典本身沒有 “a” 鍵時(shí),會(huì)自動(dòng)初始化 “a” 鍵并賦初值 0。
  • calendar 模塊:判斷星期、閏年,輸出日歷等等。
  • itertools 模塊:在本文“迭代器”小節(jié)已進(jìn)行了簡(jiǎn)要介紹。
  • logging 模塊:在調(diào)試中可能會(huì)使用。
  • urllib 模塊:這是一個(gè) HTML 請(qǐng)求模塊,常用于爬蟲。

調(diào)試與測(cè)試

Python 中有一些內(nèi)置的辦法進(jìn)行調(diào)試與測(cè)試。

斷言:assert

斷言的含義在于,如果斷言失?。‵alse),那么代碼會(huì)被終止(拋出一個(gè)AssertionError)。比如:

n = 0
assert(n != 0)
1 / n
---------------------------------------------------------------------------

AssertionError                            Traceback (most recent call last)

<ipython-input-112-e53f92f6c644> in <module>()
      1 n = 0
----> 2 assert(n != 0)
      3 1 / n


AssertionError: 

與大家一貫喜歡使用的 print 調(diào)試法相比,斷言語(yǔ)句可以用命令行參數(shù) -O 忽略。這樣所有的 assert() 語(yǔ)句都不會(huì)被執(zhí)行。

$ python -O main.py

日志調(diào)試:logging 模塊

logging 模塊支持將錯(cuò)誤日志輸出(到控制臺(tái)或者到文件)。

此乃調(diào)試神器。延伸閱讀: logging 官方基礎(chǔ)教程。

import logging
# 該行也可能通過(guò)控制臺(tái):$ python main.py --log=WARNING 的方式實(shí)現(xiàn)
logging.basicConfig(level=logging.WARNING)
n = 0
logging.warning("n = {}".format(n))
WARNING:root:n = 0

logging 模塊的靈活之處在于你可以記錄信息的級(jí)別(DEBUG,INFO,WARNING,ERROR,CRITICAL),各級(jí)別的作用如下:

  • DEBUG:最詳細(xì)的級(jí)別,所有詳細(xì)日志都會(huì)被輸出。
  • INFO:檢測(cè)代碼是否按照預(yù)期執(zhí)行。
  • WARNING:非預(yù)期的事件發(fā)生了,或者可能在近期發(fā)生(例如:低磁盤空間)。但代碼仍然執(zhí)行。
  • ERROR:發(fā)生了級(jí)別更高的問(wèn)題,某些功能無(wú)法正常實(shí)現(xiàn)。
  • CRITICAL:嚴(yán)重錯(cuò)誤,代碼可能無(wú)法繼續(xù)運(yùn)行。
    通過(guò)?filename?參數(shù),可以將日志寫入到文件。一般使用?DEBUG?級(jí)別,即輸出所有信息。

    # logging.basicConfig(filename="log.log", level=logging.DEBUG)

    默認(rèn)會(huì)將日志追加到文件末尾,如果想要覆寫文件而不是追加,使用 filemode 參數(shù):

    # logging.basicConfig(filename="log.log", filemode="w", level=logging.DEBUG)

    更改日志格格式,使用 format 參數(shù)。一般來(lái)說(shuō),常用的格式碼(格式碼后加 s 表示字符串)有:

  • %(levelname):當(dāng)前日志字串級(jí)別。
  • %(message):當(dāng)前日志字串。
  • %(asctime):當(dāng)前時(shí)間。默認(rèn) datefmt 參數(shù)為?%Y-%m-%d %I:%M:%S
    例子。下例會(huì)輸出形如:”01/23/1900 08:05:05 PM is when this event was logged.” 這樣的格式。

    # logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
    # logging.warning('is when this event was logged.')
    # 常用的格式:
    # logging.basicConfig(format="%(levelname)s: %(message)s")

    還可以通過(guò)配置文件來(lái)代替 basicConfig 命令,并進(jìn)行設(shè)置 logger 等更高級(jí)的配置。這部分可以參考:此處。

    # import logging.config
    
    # logging.config.fileConfig('logging.conf')

附錄:正則表達(dá)式

正則表達(dá)式的基礎(chǔ)內(nèi)容參考本博客的這篇博文:正則表達(dá)式。注意:如果要保存一個(gè)正則表達(dá)式供多次使用,請(qǐng)存儲(chǔ)其?compile?后的結(jié)果,避免反復(fù)編譯。

  • re.compile(exp):編譯正則表達(dá)式。
  • re.compile(exp).match(str):判斷正則表達(dá)式能否匹配一個(gè)字串。可以 bool() 結(jié)果來(lái)獲知是否匹配。

    • re.compile(exp).match(str).groups():將匹配結(jié)果返回為單個(gè)字符串(無(wú)子組時(shí))或元組(有子組時(shí))。
    • re.compile(exp).findall(str):找出字符串中所有匹配表達(dá)式的子串。返回列表。
  • re.split(exp, str):用表達(dá)式來(lái)分割字符串,相當(dāng)于 str.split() 的增強(qiáng)版。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-421771.html

    import re
    bool(re.match(r"\d", "1"))
    True
    phone_re = re.compile(r'\d{3,4}-\d{7,8}')
    phone_re.match('010-12345678').group()
    '010-12345678'
    # 如果在正則表達(dá)式中添加了子組(小括號(hào)),那么會(huì)返回子組依順序組成的一個(gè)元組
    phone_re = re.compile(r'(\d{3,4})-(\d{7,8})')
    phone_re.match('010-12345678').groups()
    ('010', '12345678')
    phone_re = re.compile(r'\d{3,4}-\d{7,8}')  # 尋找所有子串
    phone_set = '010-12345678, 021-65439876 '
    phone_re.findall(phone_set)
    ['010-12345678', '021-65439876']
    s = 'a b   c'  # 用 re.split() 處理連續(xù)的空格
    print(s.split(' '), re.split(r"\s+", s))
    ['a', 'b', '', '', 'c'] ['a', 'b', 'c']

到了這里,關(guān)于Python常用基礎(chǔ)語(yǔ)法知識(shí)點(diǎn)大全合集,看完這一篇文章就夠了的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 關(guān)于“Python”的核心知識(shí)點(diǎn)整理大全34

    關(guān)于“Python”的核心知識(shí)點(diǎn)整理大全34

    目錄 第13 章 外星人 13.1 回顧項(xiàng)目 game_functions.py 13.2 創(chuàng)建第一個(gè)外星人 13.2.1 創(chuàng)建 Alien 類 alien.py 13.2.2 創(chuàng)建 Alien 實(shí)例 alien_invasion.py 13.2.3 讓外星人出現(xiàn)在屏幕上 game_functions.py 13.3 創(chuàng)建一群外星人 13.3.1 確定一行可容納多少個(gè)外星人 注意 13.3.2 創(chuàng)建多行外星人 alien_invasion.py gam

    2024年02月04日
    瀏覽(19)
  • 關(guān)于“Python”的核心知識(shí)點(diǎn)整理大全2

    關(guān)于“Python”的核心知識(shí)點(diǎn)整理大全2

    目錄 2.1 運(yùn)行 hello_world.py 時(shí)發(fā)生的情況 第 2 章 變量和簡(jiǎn)單數(shù)據(jù)類型 2.2 變量 2.2.1 變量的命名和使用 2.2.2 使用變量時(shí)避免命名錯(cuò)誤 2.3 字符串 2.3.1 使用方法修改字符串的大小寫 在本章中,你將學(xué)習(xí)可在Python程序中使用的各種數(shù)據(jù),還將學(xué) 習(xí)如何將數(shù)據(jù)存儲(chǔ)到變量中,以及如

    2024年02月04日
    瀏覽(14)
  • 關(guān)于“Python”的核心知識(shí)點(diǎn)整理大全56

    關(guān)于“Python”的核心知識(shí)點(diǎn)整理大全56

    ? 目錄 6. 鏈接到頁(yè)面new_topic topics.html 19.1.2 添加新條目 1. 用于添加新條目的表單 forms.py 2. URL模式new_entry urls.py 3. 視圖函數(shù)new_entry() views.py 4. 模板new_entry new_entry.html 5. 鏈接到頁(yè)面new_entry topic.html 19.1.3 編輯條目 1. URL模式edit_entry urls.py 2. 視圖函數(shù)edit_entry() views.py 往期快速傳送門

    2024年01月24日
    瀏覽(19)
  • 關(guān)于“Python”的核心知識(shí)點(diǎn)整理大全5

    目錄 2. 使用方法pop()刪除元素 3. 彈出列表中任何位置處的元素 4. 根據(jù)值刪除元素 3 章 列表簡(jiǎn)介 3.3 組織列表 3.3.1 使用方法 sort()對(duì)列表進(jìn)行永久性排序 3.3.2 使用函數(shù) sorted()對(duì)列表進(jìn)行臨時(shí)排序 3.3.3 倒著打印列表 3.3.4 確定列表的長(zhǎng)度 3.5 小結(jié) 有時(shí)候,你要將元素從列表中刪除

    2024年02月05日
    瀏覽(21)
  • 關(guān)于“Python”的核心知識(shí)點(diǎn)整理大全9

    關(guān)于“Python”的核心知識(shí)點(diǎn)整理大全9

    目錄 ?編輯 5.2.4 比較數(shù)字 5.2.5 檢查多個(gè)條件 1. 使用and檢查多個(gè)條件 2. 使用or檢查多個(gè)條件 5.2.6 檢查特定值是否包含在列表中 5.2.7 檢查特定值是否不包含在列表中 banned_users.py 5.2.8 布爾表達(dá)式 5.3 if 語(yǔ)句 5.3.1 簡(jiǎn)單的 if 語(yǔ)句 5.3.2 if-else 語(yǔ)句 5.3.3 if-elif-else 結(jié)構(gòu) 5.3.4 使用多個(gè)

    2024年02月05日
    瀏覽(27)
  • 關(guān)于“Python”的核心知識(shí)點(diǎn)整理大全63

    關(guān)于“Python”的核心知識(shí)點(diǎn)整理大全63

    目錄 20.2.11 使用 Git 跟蹤項(xiàng)目文件 1. 安裝Git 2. 配置Git 3. 忽略文件 .gitignore 注意 4. 提交項(xiàng)目 20.2.12 推送到 Heroku 注意 20.2.13 在 Heroku 上建立數(shù)據(jù)庫(kù) 20.2.14 改進(jìn) Heroku 部署 1. 在Heroku上創(chuàng)建超級(jí)用戶 注意 注意 如果你閱讀完了第17章,就知道Git是一個(gè)版本控制程序,讓你能夠在每次

    2024年01月25日
    瀏覽(26)
  • 關(guān)于“Python”的核心知識(shí)點(diǎn)整理大全64

    關(guān)于“Python”的核心知識(shí)點(diǎn)整理大全64

    目錄 20.2.15 確保項(xiàng)目的安全 settings.py 20.2.16 提交并推送修改 20.2.17 創(chuàng)建自定義錯(cuò)誤頁(yè)面 1. 創(chuàng)建自定義模板 500.html settings.py settings.py 注意 views.py 20.2.18 繼續(xù)開發(fā) 往期快速傳送門??(在文章最后): 感謝大家的支持!歡迎訂閱收藏!專欄將持續(xù)更新! 當(dāng)前,我們部署的項(xiàng)目存

    2024年02月03日
    瀏覽(35)
  • 關(guān)于“Python”的核心知識(shí)點(diǎn)整理大全23

    關(guān)于“Python”的核心知識(shí)點(diǎn)整理大全23

    目錄 ?編輯 第10 章 文件和異常 10.1 從文件中讀取數(shù)據(jù) 10.1.1 讀取整個(gè)文件 pi_digits.txt file_reader.py 10.1.2 文件路徑 10.1.3 逐行讀取 file_reader.py 10.1.4 創(chuàng)建一個(gè)包含文件各行內(nèi)容的列表 10.1.5 使用文件的內(nèi)容 pi_string.py 往期快速傳送門??(在文章最后): 感謝大家的支持!歡迎訂

    2024年02月03日
    瀏覽(17)
  • 關(guān)于“Python”的核心知識(shí)點(diǎn)整理大全45

    關(guān)于“Python”的核心知識(shí)點(diǎn)整理大全45

    目錄 15.4.6 繪制直方圖 die_visual.py 注意 15.4.7 同時(shí)擲兩個(gè)骰子 dice_visual.py 15.4.8 同時(shí)擲兩個(gè)面數(shù)不同的骰子 different_dice.py 15.5 小結(jié) 第 16 章 16.1 CSV 文件格式 16.1.1 分析 CSV 文件頭 highs_lows.py 注意 16.1.2 打印文件頭及其位置 highs_lows.py 往期快速傳送門??(在文章最后): 感謝大家

    2024年02月04日
    瀏覽(16)
  • 關(guān)于“Python”的核心知識(shí)點(diǎn)整理大全57

    關(guān)于“Python”的核心知識(shí)點(diǎn)整理大全57

    目錄 3. 模板e(cuò)dit_entry edit_entry.html 4. 鏈接到頁(yè)面edit_entry topic.html 19.2 創(chuàng)建用戶賬戶 19.2.1 應(yīng)用程序 users 1. 將應(yīng)用程序users添加到settings.py中 settings.py 2. 包含應(yīng)用程序users的URL urls.py 19.2.2 登錄頁(yè)面 urls.py 1. 模板login.html login.html 2. 鏈接到登錄頁(yè)面 base.html 3. 使用登錄頁(yè)面 往期快速傳

    2024年01月24日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包