2-2-06 函数-作用域-全局和局部
作用域
作用域,可以理解为一块空间,这块空间的数据是可以共享的。通俗点来说,作用域就类似于一个房子,房子中的东西归里面的所有人共享,其他房子的人无法获取。
4.1 函数为作用域
Python以函数为作用域,所以在函数内创建的所有数据,可以此函数中被使用,无法在其他函数中被使用。
# 这是一个独立的区域
def func():
name = "武沛齐"
data_list = [11,22,33,44]
print(name,data_list)
age = 20
print(age)
# 这是一个独立的区域
def handler():
age = 18
print(age)
func()
handler()
python中是以函数为作用域
def func():
name = "武沛齐"
age = 29
print(age)
data_list = [11,22,33,44]
print(name,data_list)
for num in range(10):
print(num)
print(num)
# 永远是TURE,默认建立了value的变量,但是如果不成立的,如果最后print这个value,程序会报错
if 1 == 1:
value = "admin"
print(value)
print(value)
# 这个案例不成立,导致max_num变量不执行,print(max_num)就会报错
if 1 > 2:
max_num = 10
print(max_num)
print(max_num)
def handler():
age = 18
print(age)
handler()
func()
4.2 全局和局部
Python中以函数为作用域,函数的作用域其实是一个局部作用域。
# 全局变量(变量名大写)
COUNTRY = "中国"
CITY_LIST = ["北京","上海","深圳"]
def download():
# 局部变量
url = "http://www.xxx.com"
...
def upload():
file_name = "rose.zip"
...
全局作用域中创建的变量称之为【全局变量】,可以在全局作用域中被使用,也可以在其局部作用域中被使用
def定义的函数时局部变量,而开头的是定义的全局变量
寻找的顺序为:优先在局部作用域中寻找,如果没有则去上级作用域中寻找
。
注意:全局变量一般都是大写。
- 在局部作用域中读取全局作用域的变量。
- 但是在全局中只能找全局变量,不能找局部变量
局部作用域和全局作用域变量同名,这算啥?
# 如果全局和局部同名,局部中的print 是优先看局部中,没有后,才看全局中
COUNTRY = "中国"
CITY_LIST = ["北京","上海","深圳"]
def download():
url = "http://www.xxx.com"
CITY_LIST = ["河北","河南","山西"]
print(url)
print(COUNTRY)
print(CITY_LIST)
def upload():
file_name = "rose.zip"
print(COUNTRY)
print(CITY_LIST)
print(COUNTRY)
print(CITY_LIST)
download()
upload()
#如果全局中更新了同名变量,全局中看更新后的变量信息
COUNTRY = "中华人民共和共国"
CITY_LIST = [11,22,33]
download()
upload()
# 输出
中国
["北京","上海","深圳"]
http://www.xxx.com
中国
["河北","河南","山西"]
中国
["北京","上海","深圳"]
http://www.xxx.com
# 更新后
中华人民共和共国
["河北","河南","山西"]
中华人民共和共国
[11,22,33]
4.3 global关键字
![[assets/Pasted image 20221017211829.png]]
默认情况下,在局部作用域对全局变量只能进行:读取和修改内部元素(可变类型),无法对全局变量进行重新赋值。
- 读取
COUNTRY = "中国"
CITY_LIST = ["北京","上海","深圳"]
def download():
url = "http://www.xxx.com"
print(COUNTRY)
print(CITY_LIST)
download()
- 修改内部元素(可变类型)
COUNTRY = "中国"
CITY_LIST = ["北京","上海","深圳"]
def download():
url = "http://www.xxx.com"
print(CITY_LIST)
CITY_LIST.append("广州")
CITY_LIST[0] = "南京"
print(CITY_LIST)
download()
- 无法对全局变量重新赋值
COUNTRY = "中国"
CITY_LIST = ["北京","上海","深圳"]
def download():
url = "http://www.xxx.com"
# 不是对全部变量赋值,而是在局部作用域中又创建了一个局部变量 CITY_LIST 。
CITY_LIST = ["河北","河南","山西"]
print(CITY_LIST)
def upload():
file_name = "rose.zip"
print(COUNTRY)
print(CITY_LIST)
download()
upload()
如果想要在局部作用域中对全局变量重新赋值,则可以基于 global
关键字实现
COUNTRY = "中国"
CITY_LIST = ["北京","上海","深圳"]
def download():
url = "http://www.xxx.com"
# 在局部作用域中强制给全局变量重新赋值
global CITY_LIST
CITY_LIST = ["河北","河南","山西"]
print(CITY_LIST) # ["河北","河南","山西"]
global COUNTRY
COUNTRY = "中华人民共和国"
print(COUNTRY) # "中华人民共和国"
def upload():
file_name = "rose.zip"
print(COUNTRY) # "中华人民共和国"
print(CITY_LIST) # ["河北","河南","山西"]
download()
upload()
4.4 nolocal 关键字
改变上一级中的变量
name = 'root'
def outer():
name = "武沛齐"
def inner():
nonlocal name
name = 123
inner()
print(name)
outer()
print(name)
补充
打印的时机是不同额,内存地址发生变化导致不同的结果出现
第5题中的 v1和v3变量指向的都是函数内部维护的那个列表的内存地址。
先print(v1)时,函数内部维护的列表的值当时是{1: 2}
最后print(v3)时,函数内部维护的列表的值已被修改为{1: 2, 5: 6}
第5题中的 v1和v3变量也是指向的都是函数内部维护的那个列表的内存地址。
最后再print v1和v3 时,结果就是最终函数内部维护的列表的值,即: {1: 2, 5: 6}
判断类型:
ef func():
return 1, 2, 3
val = func()
print( type(val) == tuple) # True
print( type(val) == list) # False
print( type(val) == dict) # False
案例:
-
根据要求实现资源下载器。
-
启动后,让用户选择专区,每个专区用单独的函数实现,提供的专区如下:
- 下载 花瓣网图片专区
- 下载 抖音短视频专区
- 下载 NBA锦集 专区
-
在用户选择了某个功能之后,表示进入某下载专区,在里面循环提示用户可以下载的内容选项(已下载过的则不再提示下载)
提醒:可基于全部变量保存已下载过得资源。 -
在某个专区中,如果用户输入(Q/q)表示 退出上一级,即:选择专区。
-
在选择专区如果输入Q/q则退出整个程序。
-
每个专区实现下载的案例如下:
-
图片
# 可供用户下载的图片如下 image_dict = { "1":("吉他男神","https://hbimg.huabanimg.com/51d46dc32abe7ac7f83b94c67bb88cacc46869954f478-aP4Q3V"), "2":("漫画美女","https://hbimg.huabanimg.com/703fdb063bdc37b11033ef794f9b3a7adfa01fd21a6d1-wTFbnO"), "3":("游戏地图","https://hbimg.huabanimg.com/b438d8c61ed2abf50ca94e00f257ca7a223e3b364b471-xrzoQd"), "4":("alex媳妇","https://hbimg.huabanimg.com/4edba1ed6a71797f52355aa1de5af961b85bf824cb71-px1nZz"), }
# 下载图片示例 import request res = requests.get( url="https://hbimg.huabanimg.com/4edba1ed6a71797f52355aa1de5af961b85bf824cb71-px1nZz", headers={ "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" } ) with open("alex媳妇.png",mode="wb") as f: f.write(res.content)
-
短视频
# 可供用户下载的短视频如下 video_dict = { "1":{"title":"东北F4模仿秀",'url':"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog"}, "2":{"title":"卡特扣篮",'url':"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f3e0000bv52fpn5t6p007e34q1g"}, "3":{"title":"罗斯mvp",'url':"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f240000buuer5aa4tij4gv6ajqg"}, }
# 下载视频示例 import requests res = requests.get( url="https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f240000buuer5aa4tij4gv6ajqg", headers={ "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 FS" } ) with open('罗斯mvp.mp4', mode='wb') as f: f.write(res.content)
-
NBA
# 可供用户下载的NBA视频如下 nba_dict = { "1":{"title":"威少奇才首秀三双","url":"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300fc20000bvi413nedtlt5abaa8tg&ratio=720p&line=0"}, "2":{"title":"塔图姆三分准绝杀","url":"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0d00fb60000bvi0ba63vni5gqts0uag&ratio=720p&line=0"} }
# 下载示例 import requests res = requests.get( url="https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0d00fb60000bvi0ba63vni5gqts0uag&ratio=720p&line=0", headers={ "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 FS" } ) with open('塔图姆三分准绝杀.mp4', mode='wb') as f: f.write(res.content)
-
-
答案:
import requests
SELECTED_IMAGE_SET = set() # 已下载图片ID(序号)
SELECTED_VIDEO_SET = set()
SELECTED_NBA_SET = set()
def download(file_path, url):
res = requests.get(
url=url,
headers={
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 FS"
}
)
with open(file_path, mode='wb') as f:
f.write(res.content)
def download_image():
total_image_dict = {
"1": ("吉他男神", "https://hbimg.huabanimg.com/51d46dc32abe7ac7f83b94c67bb88cacc46869954f478-aP4Q3V"),
"2": ("漫画美女", "https://hbimg.huabanimg.com/703fdb063bdc37b11033ef794f9b3a7adfa01fd21a6d1-wTFbnO"),
"3": ("游戏地图", "https://hbimg.huabanimg.com/b438d8c61ed2abf50ca94e00f257ca7a223e3b364b471-xrzoQd"),
"4": ("alex媳妇", "https://hbimg.huabanimg.com/4edba1ed6a71797f52355aa1de5af961b85bf824cb71-px1nZz"),
}
while True:
# 构造 1.吉他男神;2.漫画美女;
text_list = []
for num, item in total_image_dict.items():
if num in SELECTED_IMAGE_SET:
continue
data = "{}.{}".format(num, item[0])
text_list.append(data)
if text_list:
text = ";".join(text_list)
else:
text = "无可下载选项"
# 输出:1.吉他男神;2.漫画美女;3.游戏地图;4.alex媳妇
print(text)
# 返回上一步
index = input("请输入要选择的序号(Q/q退出):")
if index.upper() == "Q":
return
# 选择序号 3
if index in SELECTED_IMAGE_SET:
print("已下载,无法再继续下载,请重新选择!")
continue
group = total_image_dict.get(index)
if not group:
print("序号不存在,请重新选择")
continue
# 下载图片
file_path = "{}.png".format(group[0])
download(file_path, group[1])
# 已下载集合中
SELECTED_IMAGE_SET.add(index)
def download_video():
total_video_dict = {
"1": {"title": "东北F4模仿秀",
'url': "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog"},
"2": {"title": "卡特扣篮",
'url': "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f3e0000bv52fpn5t6p007e34q1g"},
"3": {"title": "罗斯mvp",
'url': "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f240000buuer5aa4tij4gv6ajqg"},
}
while True:
text_list = []
for num, item in total_video_dict.items():
if num in SELECTED_VIDEO_SET:
continue
data = "{}.{}".format(num, item["title"])
text_list.append(data)
if text_list:
text = ";".join(text_list)
else:
text = "无可下载选项"
print(text)
index = input("请输入要选择的序号(Q/q退出):")
if index.upper() == "Q":
return
if index in SELECTED_VIDEO_SET:
print("已下载,无法再继续下载,请重新选择!")
continue
group = total_video_dict.get(index)
if not group:
print("序号不存在,请重新选择")
continue
file_path = "{}.mp4".format(group["title"])
download(file_path, group["url"])
SELECTED_VIDEO_SET.add(index)
def download_nba():
total_nba_dict = {
"1": {"title": "威少奇才首秀三双",
"url": "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300fc20000bvi413nedtlt5abaa8tg&ratio=720p&line=0"},
"2": {"title": "塔图姆三分准绝杀",
"url": "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0d00fb60000bvi0ba63vni5gqts0uag&ratio=720p&line=0"}
}
while True:
text_list = []
for num, item in total_nba_dict.items():
if num in SELECTED_NBA_SET:
continue
data = "{}.{}".format(num, item["title"])
text_list.append(data)
if text_list:
text = ";".join(text_list)
else:
text = "无可下载选项"
print(text)
index = input("请输入要选择的序号(Q/q退出):")
if index.upper() == "Q":
return
if index in SELECTED_NBA_SET:
print("已下载,无法再继续下载,请重新选择!")
continue
group = total_nba_dict.get(index)
if not group:
print("序号不存在,请重新选择")
continue
file_path = "{}.mp4".format(group["title"])
download(file_path, group["url"])
SELECTED_NBA_SET.add(index)
print("欢迎使用xxx系统")
func_dict = {
"1": download_image,
"2": download_video,
"3": download_nba
}
while True:
print("1.花瓣网图片专区;2.抖音短视频专区;3.NBA锦集专区 ")
choice = input("请选择序号:")
if choice.upper() == "Q":
break
func = func_dict.get(choice)
if not func:
print("输入错误,请重新选择!")
continue
# 进入专区
func()
简便答案:
import requests
DB = {
"1": {
"area": "花瓣网图片专区",
"total_dict": {
"1": ("吉他男神", "https://hbimg.huabanimg.com/51d46dc32abe7ac7f83b94c67bb88cacc46869954f478-aP4Q3V"),
"2": ("漫画美女", "https://hbimg.huabanimg.com/703fdb063bdc37b11033ef794f9b3a7adfa01fd21a6d1-wTFbnO"),
"3": ("游戏地图", "https://hbimg.huabanimg.com/b438d8c61ed2abf50ca94e00f257ca7a223e3b364b471-xrzoQd"),
"4": ("alex媳妇", "https://hbimg.huabanimg.com/4edba1ed6a71797f52355aa1de5af961b85bf824cb71-px1nZz"),
},
"ext": "png",
"selected": set()
},
"2": {
"area": "抖音短视频专区",
"total_dict": {
"1": {"title": "东北F4模仿秀",
'url': "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog"},
"2": {"title": "卡特扣篮",
'url': "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f3e0000bv52fpn5t6p007e34q1g"},
"3": {"title": "罗斯mvp",
'url': "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f240000buuer5aa4tij4gv6ajqg"},
},
"ext": "mp4",
"selected": set()
},
"3": {
"area": "NBA锦集专区",
"total_dict": {
"1": {"title": "威少奇才首秀三双",
"url": "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300fc20000bvi413nedtlt5abaa8tg&ratio=720p&line=0"},
"2": {"title": "塔图姆三分准绝杀",
"url": "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0d00fb60000bvi0ba63vni5gqts0uag&ratio=720p&line=0"}
},
"ext": "mp4",
"selected": set()
},
}
def download(file_path, url):
res = requests.get(
url=url,
headers={
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 FS"
}
)
with open(file_path, mode='wb') as f:
f.write(res.content)
def handler(area_info):
# 进入专区提醒
summary = "欢迎进入{}".format(area_info['area'])
print(summary)
# 专区中选择下载
while True:
text_list = []
for num, item in area_info['total_dict'].items():
if num in area_info['selected']:
continue
if type(item) == tuple:
data = "{}.{}".format(num, item[0])
else:
data = "{}.{}".format(num, item["title"])
text_list.append(data)
if text_list:
text = ";".join(text_list)
else:
text = "无可下载选项"
print(text)
index = input("请输入要选择的序号(Q/q退出):")
if index.upper() == "Q":
return
if index in area_info['selected']:
print("已下载,无法再继续下载,请重新选择!")
continue
group = area_info['total_dict'].get(index)
if not group:
print("序号不存在,请重新选择")
continue
if type(group) == tuple:
title, url = group
else:
title, url = group['title'], group['url']
file_path = "{}.{}".format(title, area_info['ext'])
download(file_path, url)
area_info['selected'].add(index)
print("欢迎使用xxx系统")
while True:
print("1.花瓣网图片专区;2.抖音短视频专区;3.NBA锦集 专区 ")
choice = input("请选择序号(Q/q退出):")
if choice.upper() == "Q":
break
# 选择序号: 去db中找对应的字典信息
area_dict = DB.get(choice)
if not area_dict:
print("输入错误,请重新选择!")
continue
# 进入专区(area_dict选择的专区信息)
handler(area_dict)