写在最前:博主最近想搞django源码,发现好多搞不明白。干脆重新康康。大概是2022年初开始的python的学习,好多其实明白的很浅。重新巩固基础,博主水平不高,不敢好为人师。个人的经验就是一定要少看多写

函数嵌套:

举例子:

name = "g2"
def run():
    name = "nico"
    def inner():
        print(name)
    return inner

hooxi = run()
hooxi()

结果是nico

如果注释,则是g2


name = "g2"
def run():
    name = "nico"
    def inner():
        print(name)
    return [inner, inner, inner]

data_list = run()
data_list[1]()
data_list[2]()

C:\Users\admin\AppData\Local\Programs\Python\Python310\python.exe D:/Code/pycharm/python的基础进阶/嵌套.py nico nico

进程已结束,退出代码0


  • 总结:
  • 优先在自己的作用域找,没有就去上级作用域。
  • 在作用域中寻找值时,要确保此次此刻值
  • 分析函数的执行,并确定函数作用域链

闭包:

将数据封装在一个包(区域)中,使用时再去里面取。

博主此次回顾的时候觉得这个思想很厉害

比如:

def run(arg):
    def inner():
        print(arg)
    return inner

v1 = run(55)
v2 = run("monsey")
v1()
v2()

比如搞一个爬虫, 搞梨视频:

装饰器:

比如:

def outer(origin):
    def inner():
        print("g2")
        res = origin()
        print("choke")
        return res

    return inner

@outer
def run1():
    print("粉丝")
    value = (1, 2, 3, 4)
    return value

@outer
def run2():
    print("观众")
    value = (6, 7, 8, 9)
    return value

run1()
run2()

g2 粉丝 choke g2 观众 choke、

使用闭包多线程pa视频:

import requests
from concurrent.futures.thread import ThreadPoolExecutor


def download_video(url):
    contId = url.split("_")[1]

    videoStatusUrl = f"https://www.pearvideo.com/videoStatus.jsp?contId={contId}"

    headers = {
        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36",
        "Referer": url
    }
    resp = requests.get(videoStatusUrl, headers=headers)
    dic = resp.json()
    srcUrl = dic['videoInfo']['videos']['srcUrl']
    systemTime = dic['systemTime']
    srcUrl = srcUrl.replace(systemTime, f"cont-{contId}")
    return requests.get(srcUrl).content


def outer(file_name):
    def write_file(response):
        content = response.result()
        with open(file_name, mode='wb') as file_object:
            file_object.write(content)

    return write_file


POOL = ThreadPoolExecutor(10)

video_dict = {
    ("拾荒老人.mp4", "https://www.pearvideo.com/video_1731984"),
    ("宝妈脱口秀.mp4", "https://www.pearvideo.com/video_1731984"),
    ("古德伍德.mp4", "https://www.pearvideo.com/video_1784888"),
    ("大爷理发.mp4", "https://www.pearvideo.com/video_1502023"),
    ("七旬老翁.mp4", "https://www.pearvideo.com/video_1501101")
}

for item in video_dict:
    future = POOL.submit(download_video, url=item[1])
    future.add_done_callback(outer(item[0]))

POOL.shutdown()

download_url要进行防盗链的处理

匿名函数:

func = lambda x: [x * i for i in range(1, 10)]
v1 = func(5)
print(v1)

或者:

func = lambda x: "g了" if x <= 15 else "赢了"
v1 = func(5)
print(v1)
v2 = func(16)
print(v2)

生成器:

生成器函数,但函数中有yield存在时,这个函数就是生产生成器函数。

生成器对象,执行生成器函数时,会返回一个生成器对象

def func():
    print(123)
    yield 1

    print(555)
    yield 2

    print(666)
    yield 3

data = func()
v1 = next(data)
print(v1)

v2 = next(data)
print(v2)

v3 = next(data)
print(v3)

应用:

import random
def func():
    count = 0
    while count < 999:
        count = count + 1
        yield random.randint(1000, 9999)
data = func()
v1 = next(data)
print(v1)

v2 = next(data)
print(v2)

推导式:

num_list = [i for i in range(10)]
print(num_list)
num_set = {i for i in range(10)}
print(num_set)
num_dict = {i: i for i in range(10)}
print(num_dict)

# 元组, 不会立刻执行,而是得到一个生成器
num_tuple = (i for i in range(10))
print(num_tuple)
for item in num_tuple:
    print(item)

比较:

列表:

def num():
    return [lambda x: i * x for i in range(4)]
result = [m(2) for m in num()] 
print(result)

元组:

def num():
    return (lambda x: i * x for i in range(4))

result = [m(2) for m in num()]  
print(result)

未完待续