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機器人控制PyRO1輸入與輸出
輸出: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個字節,從而節省空間,主要作用是保存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,接收、存儲的是一個tuplelist或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),結果如下
集合數據list
、tuple
、dict
、set
、str
generator生成器、帶yield的函數區別:生成器表達式和列表解析的區別
l=["a"for i in range(10)]
w=(“a” for i in range(10))
12常用技巧
切片獲取特定位置的元素取後10個元素:L【-10:】
每3個取一個:L【::3】
前10個每2個取一個L【:10:2】
tuple和str也可以用
(0,1,2,3,4)【:3】
'ABCDEFG' 【:3】
迭代for indict迭代
迭代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)
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)
第二行的意思是輸出哪種級別的錯誤,錯誤有debug
,info
,warning
,error
logging還有一個好處在於可以指定文件夾用作你輸出的地方
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格式
作用:實現對象序列化
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()
作用:文件的復制壓縮等
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","./")
#遍歷一個文件夾下的所有文件
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])
作用:與集合相關
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()
作用:與時間日期相關
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)