程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

2022最新Python學習筆記

編輯:Python

前言

1python的創造者是“龜叔”Guido van Rossum

2python語言的缺點

運行速度慢python是解釋型語言(不同於編譯型),代碼需要翻譯成CPU所能理解的機器碼。但是,不影響用戶交互,因為比如python需要0.1,C需要0.001s,而網絡需要1s,1.1s和1.001s沒有什麼區別代碼不能加密python只能發布源代碼,而C語言是可以只發布.exe文件

3解釋器

CPython官方自帶的解釋器。是用C語言開發的。在命令行下運行python就是啟動CPython解釋器。IPython在CPython的基礎之上發展而來的,只是在交互性方面有所增強PyPy采用JIT技術,對python進行動態編譯,主要的目的是提高執行速度Jython可以在Java平台上的Python解釋器,可以直接把Python代碼編譯成Java字節碼執行IronPython

在微軟.Net平台上的Python解釋器,可以直接把Python代碼編譯成.Net的字節碼

4命令行模式與交互模式

命令模式直接打開cmd。效果為C:\> _交互模式在cmd中輸入python。效果為>>> _

5如何執行python文件? 

在命令模式下在hello.py目錄learn下執行以下語句。在交互模式中直接輸入代碼執行

C:\learn> python hello.py

6python常用的庫以及用法

科學計算Numpy,Scipy數據分析Pandas畫圖matplotlib數據挖掘scikit-learn,nltk,pytorch/tensorflow(深度學習)游戲Pygame/Bigworld圖像PIL機器人控制PyRO

基礎語法

1輸入與輸出

輸出:print()

print('hello,world')
print('The quick brown fox', 'jumps over', 'the lazy dog')

注意,如果采用第二種方式,print()會依次打印每個字符串,遇到逗號“,”會輸出一個空格

輸入:input()

#注意,是字符串輸入
name = input()
#可以是有提示的輸入
name = input('please enter your name: ')
print('hello,', name)
#輸入兩個整數
a,b=map(int,input().split())
#輸入兩個字符串
a,b=input().split()

2數據類型

數據類型注意點整數

1十六進制如 oxff01

2_的使用:100000000=100_000000,這是因為方便看0的個數

3沒有大小限制

4 3**5=243,表示3^5

浮點數

1如1.23e8

2沒有大小限制,超出范圍就是inf(無限大)

字符串

1" "與' ':兩個都可以使用,但是如果字符串內有'的時候,需要用" "如"I‘m OK’"

2在1的情況也可以用轉義字符來解決,如'I\'m OK'

3如果字符串中有很多的字符需要轉義,但是我想''中的部分不允許被轉義,可以使用r''如下圖

4一行內如果有很多的換行符不方便使用,可以使用'''...'''如下圖

5不可變有序

布爾值

1True和False

2運算法:and        or        not

空值None

列表,

字典,

自定義數據類型

list可變有序     s = ['python', 'java', ['asp', 'php'], 'scheme'] 

tuple不可變有序  t = (1, 2)

dict可變無序    d={'Anne':96,'Bob':84,'Candy':87}

set可變不可變均可無序     s = set([1, 1, 2, 2, 3, 3])

變量

1 變量名可以是大小寫、數字和 ,不能用數字開頭

2 變量的類型可以反復賦值,以及不同的數據類型。這種變量本身類型不固定的語言稱之為動態語言

3 a=‘ABC’,內存做了兩件事情,就是創建一個‘ABC’的字符串和創建一個a的變量,並將a指向'ABC'

常量

1 Python中沒有完全的常量,一般用大寫字符表示

全局變量1 global 全局變量

總結:字符串和元組合是不可變的,字符串、元組、列表是有序的

print('\\\t\\')
print(r'\\\t\\')
print('''line1
line2
line3''')

 

3運算符號

/結果一定是浮點數//結果一定是整數,向下取整%結果一定是整數

結論://和%的結果一定是整數,因此其運算結果一定是精確的

優先級

4字符編碼

ASCII1個字節,只能是常用的幾個符號Unicode2~6個字節,與ASCII的聯系在於,用來表示ASCII是有兩個字節,其中前面一個字節是全0,主要作用是顯示給用戶看UTF-8綜合了ASCII和Unicode的字節長度,比較靈活,比如英文為1個字節,漢字是3個字節,從而節省空間,主要作用是保存字符ASCIIUnicodeUTF-8A0100000100000000 0100000101000001中x01001110 00101101

11100100 10111000 10101101

內存:Unicode
外存/浏覽器源碼/傳輸數據:UTF-8
 

5字符串

使用Unicode進行編碼

ord()字符轉化為Unicode碼,如ord(‘A’)chr()Unicode碼轉化為字符,如chr(''66)int()字符數字轉化為數值encode()字符轉化為指定編碼的bytes類型,如'ABC'.encode('ascii'),'中文’.encode('utf-8')decode()字符轉化為指定編碼的str類型,如b'ABC'.decode('ascii',errors='ignore')#ignore的意思是少量的無效字符忽略,當然也可以不加的

len()

bytes類型計算字節數,str類型計算字符數字符串名[::-1]倒序.islower() 判斷是否全部是小寫轉化為小寫s.lower()轉化為大寫s.upper()首單詞大寫s.title()首字符串字母大寫

s.capitalize()

>>> len('中文')
2
>>> len('中文'.encode('utf-8'))
6
>>> len('ABC')
3
>>> len(b'ABC')
3
#大小寫轉換
w = "100hello WORLD"
w.upper()
Out[72]: '100HELLO WORLD'
w.lower()
Out[73]: '100hello world'
w.title()
Out[74]: '100Hello World'
w.capitalize()
Out[75]: '100hello world'

注意:我們從網絡或磁盤上讀取了字節流,用的就是bytes,由於我們在操作字符串的時候經常遇到str和bytes的互相轉化,為了避免亂碼,應該堅持使用UTF-8來進行轉化,就是encode和decode後面的參數是utf-8。

str是不可變對象

>>> a = 'abc'
>>> a.replace('a', 'A')
'Abc'
#上面的實際是創建了一個新的對象
>>> a
'abc'

解釋:對於不變對象來說,調用對象自身的任意方法,也不會改變該對象自身的內容。相反,這些方法會創建新的對象並返回,這樣,就保證了不可變對象本身永遠是不可變的。

python中的不變對象有:str None

取出特定字符之間的子字符串

#此處為取出[ ]之間的字符串
m=re.findall(r"\[(.+?)\]",L)

6格式化

和c語言的輸出一樣的

%x 十六進制整數

print('%s has %d dollars'%('Tom',100))
print('%s'%(3))#這裡的3有沒有'都是可以的,因為s是可以自動轉化整數為字符串
#指定輸出幾位以及輸出的幾位前面需不需要補上0
print('%2d-%02d' % (3, 1))
#輸出的小數點數量
print('%.2f' % 3.1415926)
#輸出帶%的時候
print('%d %%' % (7))
#format()
>>> 'Hello, {0}, 成績提升了 {1:.1f}%'.format('小明', 17.125)
'Hello, 小明, 成績提升了 17.1%'
#f-string
>>> r = 2.5
>>> s = 3.14 * r ** 2
>>> print(f'The area of a circle with radius {r} is {s:.2f}')
The area of a circle with radius 2.5 is 19.62

7特殊數據類型list

列表:一種集合

裡面的元素數據類型可以不一樣,而且可以套娃,例如

s = ['python', 'java', ['asp', 'php'], 'scheme']
#即為
p = ['asp', 'php']
s = ['python', 'java', p, 'scheme']
len()如len(classmates)

a[-1]

a[-2]

獲取最後第一個元素

                ~二~

insert()插入指定位置如a.insert(1,'jack'),插入到下標為1的位置append()末尾追加元素如a.append('Anne')extend()末尾追加元素列表如a.extend(['Anne','Bob'])pop()

刪除尾部的元素如a.pop()

刪除指定位置的元素如a.pop(4)

a[2]='dudu'

替換指定位置的元素

sort()

正序排序,如a.sort()

使用lamda自定義排序,如l.sort(key=lambda x:x[1])

reverse()倒序排序,如a.reverse()index()

獲取某個元素的下標如l.index('Anne')

count()一個元素出現的次數如l.count('Anne')列表加法

合並追加

[1,2,3]+[5,3]   >>>  [1,2,3,5,3]

列表乘法

重復幾次

[1,2,3]*2  >>>  [1,2,3,1,2,3]

實現二維數組

l1=[]
i=0
while i<5:
l1.append([])
i+=1
l1.append('你好')

與random庫結合使用

L=[3,4,1,3,4,5,1]
#在列表中隨機抽取一個對象
random.choice(L)
#列表打亂
random.shuffle(L)

8特殊數據類型tuple

區別於list:初始化後不可修改

#沒有元素時
t = ()
#1個元素
t = (1,)
#2個元素時候
t = (1, 2)

注意:如果是1個元素,t=(1)是錯誤的,因為這樣既可以表示tuple又可以表示數學計算的小括號,python默認是後者,因此上述式子相當於t=1

不變指的是指的對象不變,對象的內容有可能變的,那就是list,如下

>>> t = ('a', 'b', ['A', 'B'])
>>> t[2][0] = 'X'
>>> t[2][1] = 'Y'
>>> t
('a', 'b', ['X', 'Y'])

9特殊數據類型set

與list相比,只是內部不可以重復

一般是用來當作去重工具使用

>>> s = set([1, 1, 2, 2, 3, 3])
>>> s
{1, 2, 3} #print的結果也是{}
增s.add(5)刪s.remove(4)並/交& |

10特殊數據類型dict

字典:存儲方式:鍵-值,方便快速查找。很類似一個二維數組或者指針數組

d={'Anne':96,'Bob':84,'Candy':87}
print(d['Anne'])
判斷鍵是否存在

1方式一:in
if 'Bob' in d:
    print(d['Bob'])

方式二:get()
if d.get('Bob'):
    print(d['Bob'])

2自定義返回值

print(d.get('Bobc','sorry'))

1直接d['Duduo']=88

刪d.pop('Bob')獲d['Anne']

區別:與list相比,其查找插入的速度快,不會隨著元素的增加而變慢,但是需要占用大量的內存

11條件控制語句

age = 20
if age >= 18:
print('adult')
elif age >= 6:
print('teenager')
else:
print('kid')
if <條件判斷1>:
<執行1>
elif <條件判斷2>:
<執行2>
elif <條件判斷3>:
<執行3>
else:
<執行4>

注意:python判斷從上至下,一旦一個判斷是True,下面的就不會執行了,比如上面的結果是adult

簡寫形式,類似於switch

if x:
print('True')

12循環

for...in循環:一般用於遍歷

names = ['Michael', 'Bob', 'Tracy']
for name in names:
print(name)

計算1+2+3+...+100

#range(n)是自動生成0~n的整數序列
#range(101)是從0到100,總共101個數字
sum = 0
for x in range(101):
sum = sum + x
print(sum)
#配合list使用
ls1=[i for i in range(1,101)]
print(sum(ls1))
#輸出0~100的整數
print(list(range(101)))

while循環

sum=0
n=100
while n>0:
sum+=n
n-=1
print(sum)

當然,break和continue也同樣適用

13數據類型轉換

基本數據類型轉化

>>> int('123')
123
>>> int(12.34)
12
>>> float('12.34')
12.34
>>> str(1.23)
'1.23'
>>> str(100)
'100'
>>> bool(1)
True
>>> bool('')
False

str list dict 類型轉化

#list-->str
s = ''.join(l)
#list-->dict
l1 = ['a', 'b', 'c']
l2 = [1, 2, 3]
dict(zip(l1,l2))
#str-->list
l=s.split(',')適合都是逗號或者空格的
或者
l=list(s)
#str-->dict
s = '{"id": 1, "name": "li"}'
d = eval(s)
#dict-->list
d = {'a': 1, 'b': 2, 'c': 3}
list(d)
## ['a', 'b', 'c']
list(d.keys())
## ['a', 'b', 'c']
list(d.values())
## [1, 2, 3]
#dict-->str
str(d)

尤其注意list-->dict的時候

zip的底層原理是遍歷賦值,如果l1有重復的字段那就賦l2最後一個值

l1 = ['a', 'b', 'a']
l2 = [1, 2, 3]
dict(zip(l1,l2))
## {'a': 3, 'b': 2}
dict(zip(l2,l1))
## {1: 'a', 2: 'b', 3: 'a'}

字符串常見處理

#str類型頭尾去掉符號
str2.strip( ',' )

函數

1將一個函數名賦值到一個變量

>>> a = abs # 變量a指向abs函數
>>> a(-1) # 所以也可以通過a調用abs函數
1

2自定義函數

格式 def 函數名(參數):

                函數體

def my_abs(x):
if x >= 0:
return x
else:
return -x
#使用三元表達式
def my_abs(x):
return x if x>=0 eles -x

注意:如果沒有寫return,實際也會有return的,也就是None

3空函數

pass:什麼都不做,一般用作現在還沒想好怎麼寫,但是先讓程序跑起來

def nop():
pass
if age >= 18:
pass

4返回多個值

def hello(x,y):
return x,y
print(hello(1,2))
#結果為(1,2)
a,b=hello(1,2)
#獲取返回值

由結果(1,2)可以知道其實際返回的就是一個tuple

5默認參數的函數

背景:如果我想用同一個函數的不同參數,系統會報錯說參數不對。

做法:設置默認參數默認,必選參數在前,變化大的參數在後,例如下

def power(x, n=2):
s = 1
while n > 0:
n = n - 1
s = s * x
return s

因此power(5)等價於power(5,2),而且不影響power(5,4)的使用

改變默認參數方法

power(6,n=8)

易錯知識:默認參數必須指向不變對象

def add(L=[])
L.append('END')
return L
#對象不是L的情況
>>>add([1,2,4])
[1,2,4,'END']
>>>add([2,2,2])
[2,2,2,'END']
#對象是L的情況
>>>add()
['END']
>>>add()
['END','END']

但是這樣每次add都會多一個END,我想每次只輸出一個END該怎麼辦呢?

---使用None這個不變對象

def add(L=None)
if L is None:
L=[]
L.append('END')
return L

6可變參數函數*--可擴展變值

在變量前面加上*

比如要用 a^2+b^2+c^2+...
def add(*numbers):
sum=0
for n in numbers:
sum+=n*n
return sum
#不變參數的list和tuple也可以變成可變參數,只要在其前面加上*
num=[1,2,3,4]
add[*num]

7關鍵字參數**--可擴展變值和名稱,選填

#name和sex是必選項,00是可選項,也可以進行擴充
#一般用與可選項與必選項
def person(name,sex,**oo):
print('name:',name,'sex:',sex,'other',oo)
person('a','b',city='北京',age='7')
>>> name: a sex: b other {'city': '北京', 'age': '7'}
#另外一種表現形式,就是將**oo單獨拉出來
ok={'city:':'Beijing','age:':'7'}
person('a','b',city=ok['city'],age=ok['age'])

 8命名關鍵字參數*--不可擴展值和名稱,必填

//只接收city和job作為關鍵字參數。
def person(name, age, *, city, job):
print(name, age, city, job)
person('Jack', 24, city='Beijing', job='Engineer')

實際應用類似於問卷調查中的是否有其他想法,而且要求是必填的

與關鍵字參數的不同在於它的關鍵字的不能擴展也不能修改名字

9小總結

        *argc和**kw是python的習慣寫法

可變參數*args,接收、存儲的是一個tuple

list或tuple        func(*(1, 2, 3))

關鍵字參數**kw,接收、存儲的是一個dict

直接傳入         func(a=1, b=2)

dict                  func(**{'a': 1, 'b': 2})

10遞歸函數

n!
def fact(n):
if n==1:
return 1
else:
return n*fact(n-1)
#漢諾塔問題
def move(n,a,b,c):
if n==1:
print(a,'-->',c)
else:
move(n-1,a,c,b)#將A上面的n-1個移動到b
move(1,a,b,c)#將A底層的1個移動到c
move(n-1,b,a,c)#將b上面的n-1個移動到c

可能會發生棧溢出,可以使用尾遞歸優化來解決

11 Iterable

可迭代對象,看能否直接用for循環

isinstance(~,Iterable),結果如下

集合數據listtupledictsetstrgenerator生成器、帶yield的函數

區別:生成器表達式和列表解析的區別

l=["a"for i in range(10)]
w=(“a” for i in range(10))

  1. 列表解析式的返回結果是一個list而生成器表達式的返回是一個generator
  2. generator是每次讀取部分數據,而list是一次性讀取所有的數據,因此在數據量大的時候list會非常的浪費內容
  3. 生成器最外層是(),列表最外層是[ ]
  4. 生成器只能遍歷一次,列表可以遍歷無數次

12常用技巧

切片獲取特定位置的元素

取後10個元素:L【-10:】

每3個取一個:L【::3】

前10個每2個取一個L【:10:2】

tuple和str也可以用

(0,1,2,3,4)【:3】

'ABCDEFG' 【:3】

迭代for in

dict迭代

迭代key               for key in d:

迭代value            for values in d.values()

迭代key和value   for k,v in d.items()

迭代字符串          for ch in 'ABC'

判斷能否迭代       isinstance([1,2,3],Iterable)

List實現索引+元素  for i,v in enumerate([1,2,3])

列表生成器

列表數據進行處理

[表達式 for 條件]

1到10的數 [i for i in range(1,11)]

x^x的偶數 [x*x for x in range(1,10) if x%2==0]

全排列 [m+n for m in 'ABC' for n in '123']

for 前面可以有else,但是表示的是表達式,for後面的是過濾條件,不能有else

                 

生成器根據算法推算出下一個元素,比[]的優勢在於不需要大量的存儲空間

g=(x*x for x in range(1,11))

for n in g: print(n)

#切片實現去除字符串首尾的空格
def trim(s):
l=len(s)
if s==l*(' '):
return ''
else:
while s[0]==' ':
s=s[1:]
while s[-1]==' ':
s=s[:-1]
return
#list表達式
#100以內數字,奇數為負數,偶數為0
[-x if x%2==1 else 0 for x in range(1,11)]
#generator函數實現斐波那契數列
def fib(max):
n,a,b=0,0,1
while n<max:
yield b
a,b=b,b+a
n+=1
return 'done'
print([x for x in fib(6)])
#注意,如果直接輸出fib(5)的話會返回一個generator對象
#實際上,每次執行時遇到yield停止,然後下一次的執行送yield的下面開始的
#有yield的標志都是generator函數
#楊輝三角
def triangles():
l=[1]
while(True):
yield l
x=[0]+l
y=l+[0]
l=[x[i]+y[i] for i in range(len(x))]
n = 0
results = []
for t in triangles():
results.append(t)
n = n + 1
if n == 10:
break
for t in results:
print(t)

函數式編程

1高階函數

變量既可以指向一個對象也可以指向一個函數,所以函數名可以看成指向一個函數的變量

如def add()            m=add

高階函數:函數的參數可以是另一個函數名

2 map函數

作用,將數值集進行函數計算返回數值集,返回一個generator對象

格式:map(f,l) :f為函數,l為Iterable可循環對象

def f(x):
return x*x
r=map(f,[1,2,3,4,5])
l=list(r) #list()函數讓Iterator對象變成list
print(l)
#也可以實現與list列表生成器的功能
list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))

3 reduce函數

相當於一個遞歸函數,每次將前兩個參數進行函數計算

#將數字字符串轉化為數字
from functools import reduce
d = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
def strtoint(s):
def fn(x,y):
return x*10+y
def charmnum(s):
return d[s]
return reduce(fn,map(charmnum,s))#首先將s遍歷使用charmnum變成數字list,隨後遞歸相加
print(strtoint('123412'))

4 filter()函數

作用:過濾序列

格式:fileter(f,l)f為一個函數,l為Iterable

區別:map主要用於計算,filter主要用於過濾

底層邏輯:將每個Iterable進行計算,True留False丟

5 sorted()函數

實現排序

#正常排序
sorted(L)
#倒序
sorted(L,reverse=True)
#按照特定內容排序,特定內容可理解為函數,然後對數值有一個返回
#如按照絕對值排序
sorted(L,key=abs)
#按照分數排序
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
def by_score(t):
return t[1]
L2 = sorted(L, key=by_score)
print(L2)

L.sort()和sorted(L)函數的區別

L=[1,5,4,54,5]
#sort必須要單獨的一行進行排序,print(L.sort())的輸出是None
L.sort()
print(L)
print(sorted(L))

6匿名函數lambda

作用:表示是一個表達式,也可認為是不需要命名函數的名字,隨時隨用。如下

list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))

這樣我們就不需要單獨的寫一個函數出來

當然,既然是匿名函數,他本質上還是一個函數,所以也可以賦值給變量上,如下

f = lambda x: x * x

總結:可以拿來當做一個工具,和列表表達式一起結合使用

7庫

注意:上述的幾個函數在Python3中需要導入庫functools

8裝飾器Decorator

pass

9偏函數

pass

模塊

一個.py文件就是一個模塊

mycompany.web也是一個模塊,它的文件名叫做__init__.py。每個包下面都有這個模塊,如果沒有的話,python就會把它當做普通的目錄而不是一個包。

常見的標准模塊:string、os、sys、time、re、random(random、randint、uniform等)、math(sqrt、sin、cos、exp、log)

面向對象編程OOP

1 三大特性:封裝+繼承+多態

2類

#這裡的Object指的是父類對象,如果沒有繼承的話還是要寫Object的
class Student(object):
#注意,這裡的__init__是初始化方法,第一個永遠是self,實例化的時候不需要寫上self
def __init__(self, name, score):
self.name = name
self.score = score
def print_score(self):
print('%s: %s' % (self.name, self.score))
bart = Student('Bart Simpson', 59)

注意類的寫法和初始化

3訪問限制--封裝

目的:為了安全性,或者說更方便的擴展類的屬性一些操作,而使實例化對象不能使用如對象.Name或者對象.__Name的方式來直接訪問

做法:就是在屬性的前面加上__

如果需要訪問,就建立一個set和get的方法如下

class Student(object):
def __init__(self, name, score):
self.__name = name
self.__score = score
def get_name(self):
return self.__name
def get_score(self):
return self.__score

注意:如果你使用了如Student.__Name="大白菜",隨後進行打印這個東西,結果是大白菜的,但是,實際上是沒有對它內部的屬性進行修改,底層邏輯是創建了一個新的對象

其實私有化的變量也是可以取到的,只要用如s1._Studeng__name

因此,Python中沒有完全的私有,它只是制定了一個規則讓你獲取屬性更加困難

4繼承和多態

如類class Student(object):中將object修改為父類即可

class Timer(object):
def run(self):
print('Start...')

注意:由於python有動態變量的特征,所以它不管你有什麼類,只要你這個類中有相同的名字的方法,你都可以作為超類,這種特性叫做鴨子類型(只要你長的像鴨子,可以游泳,可以走路,那你就是一個類鴨子)。

class Duck:
def quack(self):
print("嘎嘎嘎嘎。。。。。")
class Bird:
def quack(self):
print("bird imitate duck....")
class geese:
def quack(self):
print("doge imitate duck....")
def in_the_forest(duck):
duck.quack()
duck = Duck()
bird = Bird()
doge = geese()
for x in [duck, bird, doge]:
in_the_forest(x)
本來forest要求的對象只能是鴨子,但是其他類都有鴨子中quack的方法,所以也可以傳入進來

5 獲取用戶對象信息

判斷變量/函數類型type()返回Class類型判斷類類型isinstance()返回True或False得到一個對象的所有屬性和方法dir()返回list,裡面都是str判斷有沒有某個屬性或者方法hasattr()返回True或False
#type()
>>> type('str')
<class 'str'>
#判斷是函數類型怎麼辦?導入types包,用裡面的函數
>>> type(fn)==types.FunctionType
True
>>> type(abs)==types.BuiltinFunctionType
True
>>> isinstance(h, Dog)
True
#還可以用來判斷是某些類中的一種
>>> isinstance([1, 2, 3], (list, tuple))
True
>>> getattr(obj, 'z', 404) # 獲取屬性'z',如果不存在,返回默認值404
404
hasattr(obj, 'y') # 有屬性'y'嗎?同時,也包含有方法'y'嗎?

注意:

1 能用type()判斷的都可以用isinstance()進行判斷

2 isinstance判斷的是該類以及其父類(注意邏輯關系)

6 添加類屬性和實例屬性

#類屬性
class Teacher(object):
name="teacher"
實例屬性
t=Teacher()
t.sex='男'

注意,類屬性和屬性的名稱最好不要一樣的。實例屬性想要什麼就加什麼,動態性嘛

7 添加類方法和實例方法

#定義一個方法,導入MethodType方法,隨後調用Method方法
from types import MethodType
class Student(object):
pass
s=Student()
def set_age(self, age,name):
self.age = age
self.name=name
s.set_age = MethodType(set_age, s)
s.set_age = 25,'dudu'
print(s.set_age)
#類綁定方法
Student.set_age=set_age

8 __slots__

作用:表示實例的屬性和方法有哪些

#表示只能添加名字是name和set_age的屬性或者方法
class Student(object):
__slots__ =('set_age','name')

注意:子類可以定義的屬性是自身的__slots__和父類的__slots__

9 @property修飾器

目的:

1 可以直接用student1.score的方法,又可以對條件進行賦值

2 設置讀寫權限

3 使得私有變量的書寫更加簡潔

#注意,第一個@是可讀,第二個@是可寫,使用這個還是需要初始化的
class Screen(object):
def __init__(self, width):
self._width = width
@property
def width(self):
return self._width
@width.setter
def width(self,values):
self._width=values
@property
def height(self):
return self._height
@height.setter
def height(self,values):
self._height=values
@property
def resolution(self):
return self._width * self._height
s = Screen(1024)
s.height = 768
print('resolution =', s.resolution)
if s.resolution == 786432:
print('測試通過!')
else:
print('測試失敗!')

解釋為什麼在變量前面都要加_,因為這樣表示的是私有屬性,一般來說需要通過set和get方法來進行操作,但是這樣實例化後進行操作比較復雜,我還是想用原來的student.name來進行操作,所以@propert可以實現這點

10 多重繼承

做法:只要將object設置為多個父類對象如

class Dog(Mammal, Runnable):
pass

11 枚舉類

作用:除了簡單的枚舉之外,更重要的是可以當做常量

from enum import Enum, unique
@unique
class Weekday(Enum):
Sun = 0 # Sun的value被設定為0
Mon = 1
Tue = 2
Wed = 3
Thu = 4
Fri = 5
Sat = 6
#這樣可以訪問該變量
print(Weekday.Wed.value)
#變量是不可改變的,以下內容是錯誤的
Weekday.Wed.value=9

12 元類

除了使用常規的創建類外,使用type()也可以創建類

def fn(self):
print("I'm an animal")
Animal=type('Animal',(object,),dict(myself=fn))
dog=Animal()
dog.myself()

type()中的三個參數分別為

1 類名字

2 繼承的父類,注意一個父類的時候tuple()的寫法

3 方法

13 metaclass元類

作用:創建類的模板,也就是說根據metaclass創建類,根據類創建實例對象

pass(一般用不太到,太難了)

14 zip函數

作用:將n個列表合成一個n列的矩陣

a=[1,23,4,5]
b=['e','y','r','d']
for x,y in zip(a,b):
print(x,y)

錯誤調試

1 錯誤處理

try:
print('try...')
r = 10 / int('2')
print('result:', r)
except ValueError as e:
print('ValueError:', e)
except ZeroDivisionError as e:
print('ZeroDivisionError:', e)
else:
print('no error!')
finally:
print('finally...')
print('END')

注意:錯誤是有繼承關系的,所有的錯誤都繼承自BaseException,當有多個錯誤拋出的時候,要注意後面的錯誤是不是上面錯誤的子類,因為,父類會拋出子類的錯誤。

def foo(s):
return 10 / int(s)
def bar(s):
return foo(s) * 2
def main():
try:
bar('0')
except Exception as e:
print('Error:', e)
finally:
print('finally...')

當然,當有多層嵌套的時候,我們不需要在每個模塊都寫上try catch,只要在關鍵的地方寫上就可以了。如果說

2 錯誤拋出assert

def foo(s):
n = int(s)
assert n != 0, 'n is zero!'
return 10 / n

 其實和print或者return沒有什麼區別,實現的效率也不是很高

3 logging

import logging
logging.basicConfig(level=logging.INFO)
s = '0'
n = int(s)
logging.info('n = %d' % n)
print(10 / n)

第二行的意思是輸出哪種級別的錯誤,錯誤有debuginfowarningerror

logging還有一個好處在於可以指定文件夾用作你輸出的地方

IO編程

1 文件讀取

底層原理:現在的操作系統都不允許程序本身能夠讀取文件,python程序也是如此,它發了一個請求指令給OS,讓OS去讀取文件。隨後python從OS那獲取文件內容

#使用try finally,目的是就算讀取錯了也可以關閉文件
try:
f = open('/path/to/file', 'r')
print(f.read())
finally:
if f:
f.close()
#使用with,比較推薦,也不需要寫close()
with open('/path/to/file', 'r') as f:
print(f.read())
#讀取一行
f.readline()
#讀取全部,返回列表形式,每個元素就是一行內容
f.readlines()
#讀取5個字節
f.read(5)
#讀取視頻、圖片等二進制文件,使用open(~,'rb')
f = open('test.jpg', 'rb')
#讀取gbk文件和忽略錯誤
f = open('gbk.txt', 'r', encoding='gbk', errors='ignore')
#使用readline循環遍歷一個文件
with open('./t1.txt') as f:
while (True):
line = f.readline()
if not line:
break
print(line)

2 文件寫入

#重寫或創建文件
#w是寫文本,wb是寫二進制文件
with open('test.txt', 'w') as f:
f.write('\nHello, world!')
#內容追加,使用'a'
with open('test.txt', 'a') as f:
f.write('\nHello, world!')

注意:只要加了'w'或'a',文件如果沒有的話會自動創建

3 StringIO

不是以文件的形式存在,而是以字符串的形式存在

from io import StringIO
f=StringIO()
f.write("hello")
f.write("world")
print(f.getvalue())
>>> helloworld
#注意,直接使用f.read()是沒有用的
#只有當有初始化形式的時候才可以使用read()
ff=StringIO("hello zjsu")
print(ff.getvalue())

4 BytesIO

以字節的形式存在

from io import BytesIO
f = BytesIO()
#注意這裡必須要加上encode,不加上就是一個str不符合標准
f.write('中文'.encode('utf-8'))
print(f.getvalue())

5 序列化,形成JSON格式

import json
d = dict(name='Bob', age=20, score=88)
m=json.dumps(d)
print(m)

對類進行JSON格式化

import json
class Student(object):
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
s = Student('Bob', 20, 88)
print(json.dumps(s, default=lambda obj: obj.__dict__))
#核心思路是先將類實例化,隨後將類的各個屬性轉化為dict類型,最後將其轉化為JSON格式

常用內置模塊

pickle

作用:實現對象序列化

import pickle
class Person:
def __init__(self,n,a):
self.name=n
self.age=a
def show(self):
print self.name+"_"+str(self.age)
aa = Person("JGood", 2)
aa.show()
f=open('d:\\p.txt','w')
pickle.dump(aa,f,0)
f.close()
#del Person
f=open('d:\\p.txt','r')
bb=pickle.load(f)
f.close()
bb.show()

shutil

作用:文件的復制壓縮等

path=os.getcwd()
lst=os.listdir(path)
l=[]
for filename in lst:
if filename.endswith('.py'):
l.append(filename)
#復制
shutil.copy2(filename, "./question11package")
#壓縮
shutil.make_archive("./question11package", "zip","./")

os

#遍歷一個文件夾下的所有文件
lst = os.listdir(dirname)
for filename in lst
#找出所有以.py結尾的文件
if f1.endswith('.txt'):
L.append(f1)
#找出所有的後綴
for filename in lst:
listfile.append(os.path.splitext(filename)[1])

 colections

作用:與集合相關

from collections import namedtuple
#表示一個二維坐標
Point = namedtuple('Point', ['x', 'y'])
p=Point(1,2)
print(p.x)
#表示一個圓
Circle=namedtuple('Circle',['x','y','r'])
p=Circle(4,5,6)
print(p.r)
#實現隊列或棧
from collections import deque
q = deque(['a', 'b', 'c'])
#往尾部添刪元素,類似於一個棧
q.append('x')
q.pop()
#也可以往頭部添刪元素,可以實現一個雙向列表,也就是一個雙向隊列
q.appendleft('y')
q.popleft()

 datetime

作用:與時間日期相關

from datetime import datetime
# 獲取當前datetime
now = datetime.now()
#str轉換為datetime
cday = datetime.strptime('2015-6-1 18:19:59', '%Y-%m-%d %H:%M:%S')
#日期轉str
now = datetime.now()
print(now.strftime('%a, %b %d %H:%M'))
#獲取時間戳(從1970年01月01日00時00分00秒到現在的時間)
now=time.time()
#時間的加減,如計算一個月前的時間
prievetime=datetime.date.today()-datetime.timedelta(days=30)

正則表達式

簡單匹配

#匹配一個字符串,以三個整數開頭+至少一個字符+5到8個字符
'\d{3}\s+\s{5,8}'
*任意個字符+至少一個字符?0或1個字符{n}n個字符{m,n}

m到n個字符

高級匹配

#匹配字母或者下劃線開頭,19個字符的字符串
[a-zA-Z\_][0-9a-zA-Z\_]{0, 19}
A|B匹配A或B^開頭$結尾[  ]匹配集合內[^  ]除了集合外( )表達式分組

re模塊

方式一:使用compile得到regex正則表達式對象,後用regex.~(字符串)

方式二:直接re.~(正則表達式,字符串)

說白了就是字符串寫一行還是寫兩行

re.match是從字符串開頭開始匹配,如果成功返回對象,如果失敗返回None

re.search是掃描整個字符串,返回第一個匹配的對象

re.findall是掃描整個字符串,返回所有匹配的對象

返回的對象都是_sre.SRE_Match,可以使用m.group()來獲取具體值

re.match(r'^\d{3}\-\d{3,8}$', s)
re.search(r'^\d{3}\-\d{3,8}$', s)
re.findall(r'^\d{3}\-\d{3,8}$', s)

切分字符串

#對帶空格的字符串進行去空格並逐詞劃分
>>>re.split(r'\s+', 'a b c')
['a', 'b', 'c']
#對帶空格或,或;的字符串進行分割
>>> re.split(r'[\s\,\;]+', 'a,b;; c d')
['a', 'b', 'c', 'd']

分組

功能:將一個字符串分割成好幾個子字符串組

方式:()裡面就是要分組的內容

>>> m = re.match(r'^(\d{3})-(\d{3,8})$', '010-12345')
>>> m
<_sre.SRE_Match object; span=(0, 9), match='010-12345'>
>>> m.group(0)
'010-12345'
>>> m.group(1)
'010'
>>> m.group(2)
'12345'

貪婪匹配

形式:~+ 作用:匹配盡可能多的字符

非貪婪匹配,就是在+後面加上?表示盡可能匹配少的字符

#貪婪匹配
>>> re.match(r'^(\d+)(0*)$', '102300').groups()
('102300', '')
#非貪婪匹配
>>> re.match(r'^(\d+?)(0*)$', '102300').groups()
('1023', '00')

匹配所有符合條件的字符串

m=re.findall(r'\[email protected]\w+.\w+',s)

替換

#普通用法
找到用A天替換所有的a
re.sub('a','A',s)
#用匹配出來的組1替換整個匹配出來的東西
re.sub(r'www\.(.*)\..{3}',r'\1',s)
#使用pat將pat中的條件替換成color
pat=re.compile('(blue|red|white)')
r=pat.sub('color',s)
#自定義函數
#?P<>是固定寫法,表示定義了這個組叫什麼
import re
def add212(matched):
intStr=matched.group("number")
intVal=int(intStr)
addvalue=intVal+212
return str(addvalue)
s="[email protected], [email protected], [email protected]"
m=re.sub("(?P<number>\d+)",add212,s)
print(m)

環境配置:配置清華鏡像源

pip install pip -U
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

6官方提供函數

Built-in Functions — Python 3.9.10 documentation

文件讀取時候出現UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 9: ...

原因:編碼錯誤

解決方案

with open ('demo.txt','r',encoding='utf-8') as file:

快捷鍵

double Shift萬能搜素Ctrl+Alt+L格式化Ctrl+Alt+N跳轉到某個頁面Ctrl+E最近文件Crtl+Shift+F搜索本頁面內的某內容Ctrl+Shift+R替代

 Ctrl+Shift+A

輸入split v

分屏

練習題

參考文檔

Python教程 - 廖雪峰的官方網站 (liaoxuefeng.com)


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved