目錄html
裝飾順序:從下往上(被裝飾函數)
執行順序:從上往上(python代碼的執行順序)python
def outter(func): @wraps(func) def inner(*args, **kwargs): # 裝飾前作的事 return func(*args, **kwargs) # 裝飾後作的事 retur inner
給函數添加測試運行時間的功能:git
import time from functools import wraps def outter(func): @wraps(func) def inner(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) end_time = time.time() print(end_time-start_time) return res return inner @outter def time_func(): time.sleep(1) time_func()
from functools import wraps def wrappers(params1,params2,params3): def outter(func): @wraps(func) def inner(*args, **kwargs): # 裝飾前作的事 return func(*args, **kwargs) # 裝飾後作的事 return inner return outter
無參裝飾器:被裝飾的函數不須要參數,兩層
有參裝飾器:被裝飾的函數須要參數,三層正則表達式
說白了,有參裝飾器就是再無參裝飾器的基礎上又添加了一層包裝,目的:添加一個參數。那麼有沒有可能四層、五層?答案是不必。由於四層、五層就意味着傳遞了更多的參數,那麼咱們用三層就能達到效果。全部裝飾器最多三層
迭代器:迭代取值的工具 ——(用__iter__生成迭代器對象) 優勢:1.不依賴與索引取值 2.內存中只佔一份空間,不會內存溢出,節約空間,運行效率更高*(執行一次__next__取值一次,而不是一次所有取值)* 缺點:1.不能獲取指定的元素 2.只能依次日後取值
class MyIter: """num傳入 用來指定迭代次數 """ def __init__(self, num): self.num = num self.c = 0 # 迭代 def __iter__(self): return self # 取值 def __next__(self): self.c += 1 if self.c <= self.num: return "jeff" else: raise StopIteration # 循環取值 for i in MyIter(10): print(i)
一、在遍歷Foo的實例對象時,執行for...in...時,首先會先執行__iter__()方法,將此對象變爲迭代器。 二、__iter__方法返回了一個迭代器對象,然後調用next()方法進行循環
優勢:1.不依賴與索引取值 2.內存中只佔一份空間,不會內存溢出,節約空間,運行效率更高*(執行一次__next__取值一次,而不是一次所有取值)* 缺點:1.不能獲取指定的元素 2.只能依次日後取值
import time def outter(func): def inner(*args, **kwargs): print('開始調用函數。。。') res = func(*args, **kwargs) time.sleep(10) print('函數調用結束。。。') return res return inner @outter def index(): print('函數正在執行中。。。') index()
序列化: 序列:字符串 序列化:其餘數據類型轉成字符串的過程 序列化:其餘數據類型轉成字符串的過程 反序列化:字符串轉成其餘數據類型 注意: 寫入文件的數據必須是字符串(二進制) 基於網絡傳輸的數據必須是二進制
json:能夠和其餘語言玩 pickle:只能和本身(python)玩
with open(user_path, 'w', encoding='utf-8') as f: json.dump(user_dic, f, ensure_ascii=False) f.flush()
有bug,可取到重複的牌編程
import random def fried_golden_flower(): for i in range(0, 3): color = random.choice(['♥', '♠', '♦', '♣']) number = random.choice(['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']) a = color b = number point = namedtuple('撲克牌', ['color', 'number']) p = point(color, number) print(p, a+b) fried_golden_flower()
from collections import namedtuple import random def fight_against_landlords(): list = ['大鬼', '小鬼'] color = ['♥', '♠', '♦', '♣'] number = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'] for i in color: for n in number: list.append(i+n) # 打亂順序 random.shuffle(list) # 生成迭代器,避免取到重複的牌 a = list.__iter__() for i in range(0,3): list_s = [] # 將發的17張牌放在此列表中 for num in range(0, 17): list_s.append(a.__next__()) print("玩家%s:%s" % (i+1, list_s)) dizhupai = [] for i in range(0, 3): dizhupai.append(a.__next__()) print('地主牌:%s' % dizhupai) fight_against_landlords()
# 注意: 先敲課堂上的代碼,理解並記錄博客,再寫做業! ''' 1.subprocess模塊的做用? subprocess 子進程模塊 2.什麼是包?包的做用是什麼? 包是一個帶有__init__.py的文件夾,包也能夠被導入,而且能夠一併導入包下的全部模塊。 3.如何防止模塊被導入時自動執行測試功能。 僞代碼: if __name__ == '__main__': 調用執行的函數() 4.請寫出logging模塊的使用步驟: # logging配置字典 LOGGING_DICT = {...} 1.配置日誌的路徑,項目的路徑 2.配置日誌的文件(名字,建立日誌文件) 3.配置日誌字典數據 4.調用日誌模塊,並把字典數據當參數參數 5.請寫出爬蟲原理的4個過程? 整個流程: 1.發送請求:requests 2.獲取響應數據:對方機器直接返回 3.解析並提取想要的數據:re 4.保存提取後的數據:with open()保存 咱們須要作的: 1.發送請求 2.解析數據 3.保存數據 6.什麼是正則表達式與re模塊? 正則表達式:一種篩選匹配字符串的獨立技術 re模塊:pycharm利用re模塊,匹配字符串 7.使用正則表達式匹配出str1中的地址。 source = ''' <html><h1>www.baidu.com</h1></html> <html><h1>www.taobao.com</h1></html> <html><h1>www.jd.com</h1></html> <html><h1>www.oldboyedu.com</h1></html> ''' 答案1:print(re.findall('www.(?:baidu|taobao|jd|oldboyedu).com', source)) 結果:['www.baidu.com', 'www.taobao.com', 'www.jd.com', 'www.oldboyedu.com'] 答案2:print(re.findall('www\..*com', source)) 8.用正則過濾掉str3中的英文和數字,最終輸出"張全蛋 廣州" str3 = "not 404 found 張全蛋 99 廣州" 不標準答案:print(re.findall('(?:張全蛋|廣州)', str3)) 結果:['張全蛋', '廣州'] 答案:print(re.findall('[^a-z:0-9:A-Z ]{2}', str3)) 結果:['張全蛋', '廣州'] 9.複習今日以前的全部知識點!!! '''
優勢:可擴展性高 缺點:相對於面向過程複雜度高
本身——類——報錯
class Student: name = '張全蛋' def __init__(self, name): self.name = name def learn(self): print('learning...') stu1 = Student('趙鐵柱') print(stu1.name) # 結果:趙鐵柱 優先查找本身
繼承是一種建立新類的方式,在python中,新建的類能夠繼承一個或多個父類,父類又可稱爲基類或超類(super),新建的類稱爲派生類或子類
python能夠多繼承,其餘語言只能單繼承
mro(): 會把當前類的繼承關係列出來
本身-->類->報錯json
第一種:super().__init方法 class Animal(): def __init__(self, name, eat, run): self.name = name self.eat = eat self.run = run print(f'{self.name}會{self.eat}') print(f'{self.name}會{self.run}') class Sunwukong(Animal): def __init__(self, name, eat, run, aa): super().__init__(name, eat, run) self.aa = aa
第二種:父類.__init__方法 class Animal(): def __init__(self, name, eat, run): self.name = name self.eat = eat self.run = run print(f'{self.name}會{self.eat}') print(f'{self.name}會{self.run}') class Sunwukong(Animal): def __init__(self, name, eat, run, aa): Animal.__init__(self,name, eat, run) self.aa = aa
- 新式類: 1.凡是繼承object的類或子孫類都是新式類。 2.在python3中全部的類都默認繼承object,都是新式類。 - 經典類: 1.在python2中才會有經典類與新式類之分。 2.在python2中,凡是沒有繼承object的類,都是經典類。
class Parent(object): x = 1 class Child1(Parent): pass class Child2(Parent): pass print(Parent.x, Child1.x, Child2.x) # 1 1 1 Child1.x = 2 print(Parent.x, Child1.x, Child2.x) # 1 2 1 Parent.x = 3 print(Parent.x, Child1.x, Child2.x) # 3 2 3 # 結果: 1 1 1 1 2 1 3 2 3
class A(object): def test(self): print('from A') class B(A): def test(self): print('from B') class C(A): def test(self): print('from C') class D(B): def test(self): print('from D') class E(C): def test(self): print('from E') class F(D, E): def test(self): print('from F') pass # python3中校驗: FD->DB->FE->EC->CA # python2中校驗: FD->DB->BA->FE->EC
組合指的是一個對象中,包含另外一個或多個對象。
隱藏對象的屬性和實現細節,僅對外提供公共訪問方式
在內部在屬性前加'__',使屬性私有化。其實是內部替換了變量名稱 方法名 替換爲:_類名__方法名
1.讓一些關鍵的數據,變成私有更加的安全 2.不是隨意能夠更改的 3.在屬性,和方法前面加’__‘,變成私有,那麼外界就不能夠直接調用修改。 4.可是:在類的內部能夠定義一個函數,方法調用修改。使用者直接調用這個函數就能夠了。這個函數就是接口 5.能夠在這個函數、方法加條件限制,而不是任意的改動
讓使用者調用方式一致,是一個內置的裝飾器。 使用了property內置裝飾器以後,使用者調用方法時少了一個括號,致使看起來像獲取某個方法,而不是加括號執行某個函數
第一種方式:類綁定安全
import math class Circular(): # 計算面積 @classmethod def area(self,randius): res = math.pi * math.pow(randius, 2) print(f'面積爲:{res}') #計算周長 @classmethod def perimeter(self, randius): res = 2 * math.pi * randius print(f'周長爲:{res}') Circular.area(10) Circular.perimeter(10) # 結果: 面積爲:314.1592653589793 周長爲:62.83185307179586
第二種方式:對象綁定網絡
import math class Circular(): def __init__(self, randius): self.randius = randius # 計算面積 @property def area(self): res = math.pi * math.pow(self.randius, 2) print(f'面積爲:{res}') # 計算周長 @property def perimeter(self): res = 2 * math.pi * self.randius print(f'周長爲:{res}') # 生成對象 A = Circular(10) # 執行 A.area A.perimeter # 結果: 面積爲:314.1592653589793 周長爲:62.83185307179586
# @abc.abstractmethod子類必須按照父類的方法編寫 import abc class Phone(): @abc.abstractmethod def call(self): pass class Xiaomi(Phone): def call(self): print('小米手機正在打電話!') class Iphone(Phone): def call(self): print('我是閃亮蘋果BB機,正在打電話!') # 產生對象 iphone = Iphone() xiaomi = Xiaomi() # 執行 iphone.call() xiaomi.call() # 結果: 我是閃亮蘋果BB機,正在打電話! 小米手機正在打電話!
服務端:app
import socket import json import struct import os server = socket.socket() server.bind(('127.0.0.1', 8080)) server.listen(5) conn, addr = server.accept() def unload(): while True: try: hand_dict = conn.recv(4) len_dict = struct.unpack('i', hand_dict)[0] dict_json = conn.recv(len_dict) dict = json.loads(dict_json.decode('utf-8')) move_size = dict['move_size'] accept_size = 0 with open(dict['move_name'], 'wb')as f: while accept_size < move_size: accept = conn.recv(1024) f.write(accept) accept_size += len(accept) print('上傳成功!') except StopIteration as f: print(f) break def load(): while True: try: DATA_PATH = os.path.dirname(__file__) MOVE_PATH = os.path.join(DATA_PATH) # 把電影列表打包傳給客戶端 move_list = os.listdir(MOVE_PATH) move_list_json = json.dumps(move_list).encode('utf-8') hand_dict = struct.pack('i', len(move_list_json)) # 發送報頭 conn.send(hand_dict) # 發送json格式真實電影列表 conn.send(move_list_json) # 接收客戶選擇要下載的電影編號 4個字節接受編號,足夠 choice = conn.recv(4) choice = int(choice.decode('utf-8')) # 根根選擇,拿到電影名 move_name = move_list[choice] # 拼接選擇的電影路徑 move_name_path = os.path.join(MOVE_PATH, move_name) # 電影大小 move_size = os.path.getsize(move_name_path) # 作成字典 move_dict = {'move_name': move_name, 'move_size': move_size} # 序列化 move_json = json.dumps(move_dict).encode('utf-8') hand_dict = struct.pack('i', len(move_json)) # 發送報頭,和json格式字典 conn.send(hand_dict) conn.send(move_json) with open(move_name_path, 'rb')as f: for i in f: conn.send(i) print('下載成功!') except StopIteration as f: print(f) break def run(): res = conn.recv(4) res = res.decode('utf-8') if res == '1': unload() elif res == '2': load() run() server.close()
客戶端:dom
import socket import json import os import struct client = socket.socket() client.connect(('127.0.0.1', 8080)) # 上傳電影 def unload(): while True: print('---下載電影---') # 拼接路徑 MOVE_PATH = os.path.join('D:\PS素材') move_list = os.listdir(MOVE_PATH) for index, move_name in enumerate(move_list): print(index, move_name) choice = input('請選擇電影編號(q.退出):').strip() if choice == 'q': break if not choice.isdigit(): print('輸入數字!') continue choice = int(choice) if choice not in range(len(move_list)): print('不在範圍!') continue move_name = move_list[choice] move_name_path = os.path.join(MOVE_PATH, move_name) move_size = os.path.getsize(move_name_path) move_dict = {'move_name': move_name, 'move_size': move_size} move_json = json.dumps(move_dict).encode('utf-8') hand_dict = struct.pack('i', len(move_json)) client.send(hand_dict) client.send(move_json) with open(move_name_path, 'rb')as f: for i in f: client.send(i) print('上傳成功!') # 下載電影 def load(): while True: print('---下載電影---') hand_dict = client.recv(4) len_dict = struct.unpack('i', hand_dict)[0] # 接收了json格式的列表 dict_json = client.recv(len_dict) # 解碼電影列表 move_list = json.loads(dict_json.decode('utf-8')) # 打印列表,展現 for index, move_name in enumerate(move_list): print(index, move_name) while True: choice = input('選擇你要下載的電影編號 (q.退出):').strip() if choice == 'q': run() if not choice.isdigit(): print('輸入數字!') continue choice = int(choice) if choice not in range(len(move_list)): print('輸入不規範!') continue # 若是輸入規範,把用戶選擇的編號傳給客戶端 choice = str(choice).encode('utf-8') client.send(choice) hand_dict = client.recv(4) len_dict = struct.unpack('i', hand_dict)[0] dict_json = client.recv(len_dict) dict = json.loads(dict_json.decode('utf-8')) move_size = dict['move_size'] accept_size = 0 with open(dict['move_name'], 'wb')as f: while accept_size < move_size: accept = client.recv(1024) f.write(accept) accept_size += len(accept) print('下載成功!') continue def run(): while True: print(''' 1:【上傳電影】 2:【下載電影】 q:退出 ''') choice = input('請選擇功能:').strip() if choice == '1': client.send(choice.encode('utf-8')) unload() elif choice == '2': client.send(choice.encode('utf-8')) load() elif choice == 'q': break else: print('輸入不規範!') continue if __name__ == '__main__': run()
int 其餘進制轉十進制 a = int('0b1010011010', 2) b = int('0o1232', 8) c = int('0x29a', 16) print(a,b,c) # 結果: 666 666 666 bin 十進制轉二進制 aa = bin(666) print(aa) # 結果 :0b1010011010 oct 十進制轉八進制 bb = oct(666) print(bb) # 結果 :0o1232 oct 十進制轉八進制 bb = oct(666) print(bb) # 結果 :0o1232
第一種: res = a.encode('utf-8') # 編碼 print(res.decode('utf-8')) # 解碼 第二種: res1 = bytes(a, encoding='utf-8') # 編碼二進制 res2 = str(res1, encoding='utf-8') # 解碼二進制