Python學習筆記,
最近在看《Python教程》,所以把一些記錄一下,以後自己看的話,複習會比較快。
print("我是***","你呢?",1,2,True)#逗號會換成空格,然後拼接name=input("你的名字:")#輸入字串數值:整數、浮點數、字串、空值、布爾布爾運算:and or notstr運算:'1'.replace('1','2')isinstance(x, (int, float))檢查x是否屬於int或floatprint(ord('a'))#編碼print(chr(97))
list和tuple
#list 其中元素可以不同names=['Bob','Mary','Jack']print(len(names))print(names[0])print(names[-1])names.append('Dav')#追加names.insert(1,'Kery')#插入,第一個參數是位置names.pop(3)#刪除指定位置names[1]='Arry'#替換names.sort()#排序#tuple 元組,和list相似(中括弧換成小括弧,其他方法一樣可以用),但是初始化後不能改#因為在數學公式中也有小括弧,所以有一個元素是必須加一個逗號,t=(1,)#tuple的不變表示指向不變,比如元組中有一個list,list的指向不變,但是list中的值可以變t=(1,2,[1,2])t[2][0]=5
條件判斷和迴圈
#條件判斷cl=5if cl<=6: print('小學')elif cl<=9: print('初中')elif cl<=12: print('高中')else: print('大學或沒讀')#迴圈names=['Bob','Mary','Jack']for name in names: print(name)n=0while n<len(names): print(names[n]) n=n+1
dict和set
#dict 字典,索引值對形式,尋找速度快,key不可變,所以key不能為listd={'1':1,'2':2}print(d['1'])d['1']=11#改變值if '1' in d:#避免key不存在報錯 print(d['1'])print(d.get('1'))#如果key不存在,返回Noned.pop('1')#刪除該值,value也會被刪除掉for k,v in d.items: print(k,v)#==============================================================================# dict內部存放的順序和key放入的順序是沒有關係的。# 和list比較,dict有以下幾個特點:# 尋找和插入的速度極快,不會隨著key的增加而變慢;# 需要佔用大量的記憶體,記憶體浪費多。# 而list相反:# 所以,dict是用空間來換取時間的一種方法。#==============================================================================#set key的集合, 不能重複,s1=set([1,2,3,4,1,23,3,4])#重複元素自動過濾s1.add(20)s1.remove(20)s2=set([5,4,3])#set可以看成數學意義上的無序和無重複元素的集合,因此,兩個set可以做數學意義上的交集、並集等操作:print(s1&s2)print(s1|s2)
內建函數、函數、參數
#python內建函數abs(100)max(1,2,3,5)min(1,2,3,4)int('123')float('123.43')str(1.24)bool(1)#函數def nop(): pass#==============================================================================# #參數# *args是可變參數,args接收的是一個tuple;# **kw是關鍵字參數,kw接收的是一個dict。#==============================================================================
切片
#切片 list、tuple、str可用names=['Bob','Mary','Jack']print(names[0:2])print(names[:2])print(names[-2:])#print(names[:3:2])#每兩個取一個
迭代
#迭代 from collections import Iterableprint(isinstance('abc',Iterable))#內建的enumerate函數可以把一個list變成索引-元素對for i,value in enumerate(['1','2','3','4']): print(i,value)
列表產生式、產生器
#列表產生式print(list(range(1,33)))l=[x*x for x in range(1,4)]print(l)l=[x*x for x in range(1,11) if x%2==0]print(l)l=[m+n for m in 'ABC' for n in 'XYZ']print(l)#產生器 generator generator儲存的是演算法g=(x*x for x in range(1,4))#將中括弧換成小括弧就是產生器print(next(g))#列印下一個值,到最後一個會報錯,所以用for迴圈#將print換成yield ,函數變成了generator
map、reduce、filter
#map map(fun,Iterable) 將傳入的函數依次作用到序列的每個元素,並把結果作為新的Iterator返回def f(x): return x*xprint(list(map(f,[1,2,3,4])))#reduce reduce(fun,Iterable) 把結果繼續和序列的下一個元素做累積計算from functools import reducedef add(x,y): return x+yprint(reduce(add,[1,2,3,4]))#filter filter(fun,Iterable) 把傳入的函數依次作用於每個元素,然後根據傳回值是True還是False決定保留還是丟棄該元素。def is_odd(x): return x%2==1print(list(filter(is_odd,[1,2,3,4,5])))
排序小例子
#=============排序問題=================================================================# def by_name(t):# return t[0]# L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]# print(sorted(L,key=by_name))# print(sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True))#忽略大小寫# #==============================================================================
匿名函數、閉包
#匿名函數print(list(map(lambda x:x*x,[1,2,3])))#閉包def count(): fs = [] def f(x): return lambda: x*x#通過匿名函數 for i in range(1, 4): fs.append(f(i)) return fsf1,f2,f3=count()print(f1(),f2(),f3())
裝飾器小例子
#裝飾器 運行看看import functoolsdef logger(text): def decorator(func): @functools.wraps(func) def wrapper(*args, **kw): print('%s %s():' % (text, func.__name__)) return func(*args, **kw) return wrapper return decorator@logger('DEBUG')def today(): print('2015-3-25')today()
偏函數
#偏函數 可以降低函數調用的難度import functoolsmax2=functools.partial(max,10)print(max2(1,2,3,4))#自動把10放在比較數值中#==============================================================================# #一個.py檔案稱之為一個模組#==============================================================================
類和執行個體
#類和執行個體 #變數名類似__xxx__的,也就是以雙底線開頭,並且以雙底線結尾的,是特殊變數,特殊變數是可以直接存取的,不是private變數,class Student(object): def __init__(self,name,score):#_init__方法的第一個參數永遠是self,表示建立的執行個體本身 self.__name=name#表示私人 self.__score=score#_name,這樣的執行個體變數外部是可以訪問的,意思就是,“雖然我可以被訪問,但是,請把我視為私人變數,不要隨意訪問”。 def print_score(self): print(self.__name,self.__score) def get_name(self): return self.__name def set_name(self,name): self.__name=name def set_score(self,score): self.__score=score def get_score(self): return self.__scores=Student('Bart',14)#__name不能訪問是因為將其改成了_St05udent__nameprint(s._Student__name)s.__name='123'#內部的__name變數已經被Python解譯器自動改成了_Student__name,而外部代碼給bart新增了一個__name變數。print(s.get_name())#沒有被改變s.print_score()#繼承和多態 class ChuStudent(Student):#初中生繼承了學生 def set_score(self,score): if score<=100: self.__score=score else: print('得分有誤')chu=ChuStudent('123',40)chu.set_score(143)chu.print_score()#擷取物件類型print(type(123))import types#判斷一個對象是否是函數print(type(lambda x:x*x)==types.LambdaType)print(isinstance('a', str))print(dir('123'))#擷取全部屬性和方法print(hasattr(chu,'name'))#是否有name屬性setattr(chu,'age',10)#設定屬性print(getattr(chu,'age'))#擷取屬性print(chu.age)#擷取屬性 如果不存在會拋出AttributeError的錯誤print(getattr(chu,'z',404))#最後賦予預設值#Binder 方法def set_age(self,age): self.age=agefrom types import MethodTypes.set_age=MethodType(set_age,s)s.set_age(120)print(s.age)#若給所有執行個體Binder 方法ChuStudent.set_age=set_age#限制執行個體的屬性class XiaoStudnet(Student): __slots__=('name','score','age')# 用tuple定義允許綁定的屬性名稱
@property使用
# =============================================================================# #@property# class Student(object):#birth是可讀寫屬性,而age就是一個唯讀屬性,# @property# def birth(self):# return self._birth# # @birth.setter# def birth(self, value):# self._birth = value# # @property# def age(self):# return 2015 - self._birth# # #多重繼承# class Object1(Object2,Object3....):# pass# =============================================================================
為執行個體添加一個列印,相當於java中重寫toString
# =============================================================================# #為執行個體添加一個列印顯示# class Student(object):# def __init__(self, name):# self.name = name# def __str__(self):# return 'Student object (name=%s)' % self.name# __repr__ = __str__# # print(Student("123"))# =============================================================================
將對象可以使用for迴圈
# =============================================================================# #如果一個類想被用於for ... in迴圈,類似list或tuple那樣,就必須實現一個__iter__()方法,該方法返回一個迭代對象# class Fib(object):# def __init__(self):# self.a, self.b = 0, 1 # 初始化兩個計數器a,b# # def __iter__(self):# return self # 執行個體本身就是迭代對象,故返回自己# # def __getitem__(self, n):#直接f[]顯示# if isinstance(n, int): # n是索引# a, b = 1, 1# for x in range(n):# a, b = b, a + b# return a# if isinstance(n, slice): # n是切片# start = n.start# stop = n.stop# if start is None:# start = 0# a, b = 1, 1# L = []# for x in range(stop):# if x >= start:# L.append(a)# a, b = b, a + b# return L# def __getattr__(self, attr):#防止不存在的屬性,報錯# if attr=='score':# return 99# def __call__(self):#可以直接對執行個體進行調用 s()# print('My name is %s.' % self.name)# def __next__(self):# self.a, self.b = self.b, self.a + self.b # 計算下一個值# if self.a > 100000: # 退出迴圈的條件# raise StopIteration()# return self.a # 返回下一個值# =============================================================================
枚舉
# =============================================================================# #如果一個類想被用於for ... in迴圈,類似list或tuple那樣,就必須實現一個__iter__()方法,該方法返回一個迭代對象# class Fib(object):# def __init__(self):# self.a, self.b = 0, 1 # 初始化兩個計數器a,b# # def __iter__(self):# return self # 執行個體本身就是迭代對象,故返回自己# # def __getitem__(self, n):#直接f[]顯示# if isinstance(n, int): # n是索引# a, b = 1, 1# for x in range(n):# a, b = b, a + b# return a# if isinstance(n, slice): # n是切片# start = n.start# stop = n.stop# if start is None:# start = 0# a, b = 1, 1# L = []# for x in range(stop):# if x >= start:# L.append(a)# a, b = b, a + b# return L# def __getattr__(self, attr):#防止不存在的屬性,報錯# if attr=='score':# return 99# def __call__(self):#可以直接對執行個體進行調用 s()# print('My name is %s.' % self.name)# def __next__(self):# self.a, self.b = self.b, self.a + self.b # 計算下一個值# if self.a > 100000: # 退出迴圈的條件# raise StopIteration()# return self.a # 返回下一個值# =============================================================================
錯誤處理
# =============================================================================# #錯誤處理# try:# r=10/0# except Exception as e:# print(e)# finally:# print('finally...')# # print('end')# =============================================================================
讀寫檔案
# =============================================================================# #讀寫檔案# try:# f=open('test.txt','r')# print(f.read())# finally:# if f:# f.close()# # with open('test.txt','r') as f:# print(f.read())# #防止檔案過大,一行一行讀# for line in f.readline():# print(line.strip())# # with open('test.txt','w') as f:# f.write('Hello,world!')# =============================================================================
StringIO和BytesIO
#StringIO 記憶體中讀寫strfrom io import StringIOf=StringIO()print(f.write('hello'))s=f.getvalue()from io import StringIOf=StringIO('Hello!')while True: s=f.readline() if s=='': break print(s.strip())from io import BytesIOf=BytesIO()print(f.write("中文".encode('utf-8')))print(f.getvalue())from io import BytesIOf=BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')print(f.read())
操作目錄和檔案
#操作檔案和目錄import osprint(os.name)#posix是linux系統,nt是windows系統print(os.environ)#環境變數print(os.environ.get('PATH'))#某個環境變數print(os.path.abspath('.'))#查看目前的目錄的絕對路徑print(os.path.join('C:\\Users\\Administrator\\Desktop\\PythonLeaning','testdir'))#將兩個目錄拼起來print(os.mkdir('C:\\Users\\Administrator\\Desktop\\PythonLeaning\\testdir'))#建立目錄print(os.rmdir('C:\\Users\\Administrator\\Desktop\\PythonLeaning\\testdir'))print(os.path.split('C:\\Users\\Administrator\\Desktop\\PythonLeaning'))#拆分路徑,最後一個拆出來print(os.path.splitext('C:\\Users\\Administrator\\Desktop\\PythonLeaning\\test.txt'))#獲得副檔名#這些合并、拆分路徑的函數並不要求目錄和檔案要真實存在,它們只對字串進行操作。print(os.rename('test.txt','test.py'))#重新命名print(os.remove('test.py'))#刪除檔案print([x for x in os.listdir('.') if os.path.isdir(x)])#累出目前的目錄下所有目錄print([x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.py'])#列出所有.py的檔案
序列化和JSON
#序列化 :把變數從記憶體中變成可儲存或傳輸的過程稱之為序列化import pickled=dict(name='Bob',age=20,score=88)f=open('dump.txt','wb')pickle.dump(d,f)f.close()f=open('dump.txt','rb')d=pickle.load(f)f.close()print(d)#JSON import jsond=dict(name='Bob',age=20,score=99)print(json.dumps(d))#返回的是標準的json格式json_str='{"name": "Bob", "age": 20, "score": 99}'print(json.loads(json_str))#執行個體序列化class Student(object): def __init__(self,name,age,score): self.name=name self.age=age self.score=score def student2dit(std): return { 'name':std.name, 'age':std.age, 'score':std.score }s=Student('Bob',20,99)print(json.dumps(s,default=student2dit))print(json.dumps(s,default=lambda obj:obj.__dict__))#通常class的執行個體都有一個__dict__屬性,它就是一個dict,用來儲存執行個體變數。#還原序列化def dict2student(d): return Student(d['name'],d['age'],d['score'])print(json.loads(json_str,object_hook=dict2student))
線程
#線程 python的os模組封裝了常見的系統調用,import osfrom multiprocessing import Process#子線程要執行的代碼def run_proc(name): print(name,os.getpid()) if __name__=='__main__': print(os.getpid()) p=Process(run_proc('test')) print('啟動') p.start() p.join()#等待子進程結束後再繼續往下運行,通常用於進程間的同步。 print('結束')#如果要啟動大量的子進程,可以用進程池的方式大量建立子進程from multiprocessing import Poolimport time,randomdef long_time_task(name): print(name,os.getpid()) start=time.time() time.sleep(random.random()*3) end=time.time() print(name,(end-start))if __name__=='__main__': print('等待完成') print(os.getpid()) p=Pool(4) for i in range(5): p.apply_async(long_time_task(i)) p.close() p.join() print('完成')from multiprocessing import Process, Queueimport os, time, random# 寫資料進程執行的代碼:def write(q): print('Process to write: %s' % os.getpid()) for value in ['A', 'B', 'C']: print('Put %s to queue...' % value) q.put(value) time.sleep(random.random())# 讀資料進程執行的代碼:def read(q): print('Process to read: %s' % os.getpid()) while True: value = q.get(True) print('Get %s from queue.' % value)if __name__=='__main__': # 父進程建立Queue,並傳給各個子進程: q = Queue() pw = Process(target=write(q,)) pr = Process(target=read(q,)) # 啟動子進程pw,寫入: pw.start() # 啟動子進程pr,讀取: pr.start() # 等待pw結束: pw.join() # pr進程裡是死迴圈,無法等待其結束,只能強行終止: pr.terminate()#全域變數local_school就是一個ThreadLocal對象,每個Thread對它都可以讀寫student屬性,但互不影響。你可以把local_school看成全域變數,但每個屬性如local_school.student都是線程的局部變數,可以任意讀寫而互不干擾,也不用管理鎖的問題,ThreadLocal內部會處理。#可以理解為全域變數local_school是一個dict,不但可以用local_school.student,還可以綁定其他變數,如local_school.teacher等等。#ThreadLocal最常用的地方就是為每個線程綁定一個資料庫連接,HTTP請求,使用者身份資訊等,這樣一個線程的所有調用到的處理函數都可以非常方便地訪問這些資源。import threading# 建立全域ThreadLocal對象:local_school = threading.local()def process_student(): # 擷取當前線程關聯的student: std = local_school.student print('Hello, %s (in %s)' % (std, threading.current_thread().name))def process_thread(name): # 綁定ThreadLocal的student: local_school.student = name process_student()t1 = threading.Thread(target= process_thread, args=('Alice',), name='Thread-A')t2 = threading.Thread(target= process_thread, args=('Bob',), name='Thread-B')t1.start()t2.start()t1.join()t2.join()