開發者筆記

目錄html

1.疊加裝飾器的裝飾順序與執行順序

裝飾順序:從下往上(被裝飾函數)
執行順序:從上往上(python代碼的執行順序)python

1.1無參裝飾器模板:

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()

1.2有參裝飾器

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

2.什麼是無參裝飾器與有參裝飾器

無參裝飾器:被裝飾的函數不須要參數,兩層
有參裝飾器:被裝飾的函數須要參數,三層正則表達式

說白了,有參裝飾器就是再無參裝飾器的基礎上又添加了一層包裝,目的:添加一個參數。那麼有沒有可能四層、五層?答案是不必。由於四層、五層就意味着傳遞了更多的參數,那麼咱們用三層就能達到效果。全部裝飾器最多三層

3.簡述可迭代對象,迭代器對象及迭代取值方式,及for循環內部原理

3.1迭代器

迭代器:迭代取值的工具 ——(用__iter__生成迭代器對象)

優勢:1.不依賴與索引取值

   2.內存中只佔一份空間,不會內存溢出,節約空間,運行效率更高*(執行一次__next__取值一次,而不是一次所有取值)*

缺點:1.不能獲取指定的元素

   2.只能依次日後取值

3.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)

3.2 for 循環內部原理

一、在遍歷Foo的實例對象時,執行for...in...時,首先會先執行__iter__()方法,將此對象變爲迭代器。
二、__iter__方法返回了一個迭代器對象,然後調用next()方法進行循環

4.迭代器對象的優缺點是什麼?

優勢:1.不依賴與索引取值

   2.內存中只佔一份空間,不會內存溢出,節約空間,運行效率更高*(執行一次__next__取值一次,而不是一次所有取值)*

缺點:1.不能獲取指定的元素

   2.只能依次日後取值

5.請實現一個裝飾器,限制該函數被調用的頻率,如10秒一次

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()

6.什麼是序列化?什麼是反序列化?爲何要這麼作?

序列化:
序列:字符串
序列化:其餘數據類型轉成字符串的過程
  序列化:其餘數據類型轉成字符串的過程
  反序列化:字符串轉成其餘數據類型

注意:
  寫入文件的數據必須是字符串(二進制)
  基於網絡傳輸的數據必須是二進制

7.什麼是json與picjle的區別是什麼?

json:能夠和其餘語言玩

pickle:只能和本身(python)玩

8.ATM的登陸與註冊功能,用戶數據用json數據保存。

with open(user_path, 'w', encoding='utf-8') as f:
        json.dump(user_dic, f, ensure_ascii=False)
        f.flush()

9.寫一個撲克牌隨機發牌遊戲

飄三葉:

有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()

10.爬蟲正則

# 注意: 先敲課堂上的代碼,理解並記錄博客,再寫做業! 
'''
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.複習今日以前的全部知識點!!!
'''

11.面向對象編程的優缺點是什麼?

優勢:可擴展性高
缺點:相對於面向過程複雜度高

12.對象的屬性查找順序是什麼?

本身——類——報錯
class Student:
    name = '張全蛋'
    def __init__(self, name):
        self.name = name
        
    def learn(self):
        print('learning...')

stu1 = Student('趙鐵柱')
print(stu1.name)


# 結果:趙鐵柱    優先查找本身

13.什麼是繼承?繼承的目的?

繼承是一種建立新類的方式,在python中,新建的類能夠繼承一個或多個父類,父類又可稱爲基類或超類(super),新建的類稱爲派生類或子類

14.python與期他語言的繼承區別是什麼?

python能夠多繼承,其餘語言只能單繼承

15.如何尋找繼承關係?

mro(): 會把當前類的繼承關係列出來

16.繼承背景下對象屬性的查找順序是什麼?

本身-->類->報錯json

17.什麼是派生?如何重用父類的屬性並派生?兩種方式

第一種: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

18.什麼是新式類與經典類?

- 新式類:
    1.凡是繼承object的類或子孫類都是新式類。
    2.在python3中全部的類都默認繼承object,都是新式類。

- 經典類:
    1.在python2中才會有經典類與新式類之分。
    2.在python2中,凡是沒有繼承object的類,都是經典類。

19.鑽石繼承下,經典類與新式類屬性的查找順序是什麼?

20.下面這段代碼的輸出結果將是什麼?請解釋。

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

21.下述代碼新式類與新式類的查找順序是什麼?

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

22.什麼是組合?爲何要使用組合?

組合指的是一個對象中,包含另外一個或多個對象。

23.什麼是封裝?

隱藏對象的屬性和實現細節,僅對外提供公共訪問方式

24.什麼是訪問限制機制?

在內部在屬性前加'__',使屬性私有化。其實是內部替換了變量名稱   方法名   替換爲:_類名__方法名

25.訪問限制機制的優勢?

1.讓一些關鍵的數據,變成私有更加的安全
2.不是隨意能夠更改的
3.在屬性,和方法前面加’__‘,變成私有,那麼外界就不能夠直接調用修改。
4.可是:在類的內部能夠定義一個函數,方法調用修改。使用者直接調用這個函數就能夠了。這個函數就是接口
5.能夠在這個函數、方法加條件限制,而不是任意的改動

26.什麼是property?爲何要使用property?

讓使用者調用方式一致,是一個內置的裝飾器。
使用了property內置裝飾器以後,使用者調用方法時少了一個括號,致使看起來像獲取某個方法,而不是加括號執行某個函數

27.輸入半徑,計算圓的面積、周長

第一種方式:類綁定安全

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

2八、使用abc模塊定義一個Phone手機抽象類,讓全部子類都繼承手機抽象類,讓不一樣牌子的手機都必須遵循抽象類手機打電話的步驟。

# @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機,正在打電話!
小米手機正在打電話!

29 上傳下載電影

服務端: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()

30.二進制轉其餘字符類型:

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

31.decode、endoce

第一種:
    res = a.encode('utf-8')  # 編碼
    print(res.decode('utf-8'))  # 解碼
第二種:
    res1 = bytes(a, encoding='utf-8')  # 編碼二進制
    res2 = str(res1, encoding='utf-8')  # 解碼二進制
相關文章
相關標籤/搜索