函数名其实就是一个变量,这个变量只不过代指的函数而已。
name = "华青水上"
def add(n1,n2):
return n1 + n2
注意:函数必须先定义才能被调用执行(解释型语言)。
# 正确
def add(n1,n2):
return n1 + n2
ret = add(1,2)
print(ret)
# 错误
ret = add(1,2)
print(ret)
def add(n1,n2):
return n1 + n2
1、函数做元素
既然函数就相当于是一个变量,那么在列表等元素中是否可以把函数当做元素呢?
def func():
return 123
data_list = ["华青水上", "func", func , func() ]
print( data_list[0] ) # 字符串"华青水上"
print( data_list[1] ) # 字符串 "func"
print( data_list[2] ) # 函数 func
print( data_list[3] ) # 整数 123
res = data_list[2]()
print( res ) # 执行函数 func,并获取返回值;print再输出返回值。
print( data_list[2]() ) # 123
注意:函数同时也可被哈希,所以函数名通知也可以当做 集合的元素、字典的键。
掌握这个知识之后,对后续的项目开发有很大的帮助,例如,在项目中遇到根据选择做不同操作时:
情境一、要开发一个类似于微信的功能。
def send_message():
"""发送消息"""
pass
def send_image():
"""发送图片"""
pass
def send_emoji():
"""发送表情"""
pass
def send_file():
"""发送文件"""
pass
print("欢迎使用xx系统")
print("请选择:1.发送消息;2.发送图片;3.发送表情;4.发送文件")
choice = input("输入选择的序号")
# 方法一
"""
if choice == "1":
send_message()
elif choice == "2":
send_image()
elif choice == "3":
send_emoji()
elif choice == "4":
send_file()
else:
print("输入错误")
"""
# 方法二
function_dict = {
"1": send_message,
"2": send_image,
"3": send_emoji,
"4": send_file,
"5": xxx
}
func = function_dict.get(choice)
if not func:
print("输入错误")
else:
# 执行函数
func()
在情境一案例中,方法一使用的是常用if语句判断法实现的功能,方法二中将函数名作为了字典对应键的值实现了其功能。
情境二、某个特定情况,要实现发送短信、微信、邮件。
def send_msg():
"""发送短信"""
pass
def send_email():
"""发送图片"""
pass
def send_wechat():
"""发送微信"""
# 方法一
"""
# 执行函数
send_msg()
send_email()
send_wechat()
"""
# 方法二
func_list = [ send_msg, send_email, send_wechat ]
for item in func_list:
item()
在情境二案例中,方法一使用正常的函数名后面加括号就可以执行,方法二是将函数名添加到了一个列表中,通过for循环依次去自动执行每一个函数。
上述两种情景,在参数相同时才可用,如果参数不一致,会出错。所以,在项目设计时就要让程序满足这一点,如果无法满足,也可以通过其他手段来实现,例如:
情景一
def send_message(phone,content):
"""发送消息"""
pass
def send_image(img_path, content):
"""发送图片"""
pass
def send_emoji(emoji):
"""发送表情"""
pass
def send_file(path):
"""发送文件"""
pass
function_dict = {
"1": [ send_message, ['15131255089', '你好呀']],
"2": [ send_image, ['xxx/xxx/xx.png', '消息内容']],
"3": [ send_emoji, ["😁"]],
"4": [ send_file, ['xx.zip'] ]
}
print("欢迎使用xx系统")
print("请选择:1.发送消息;2.发送图片;3.发送表情;4.发送文件")
choice = input("输入选择的序号") # 1
item = function_dict.get(choice) # [ send_message, ['15131255089', '你好呀']],
if not item:
print("输入错误")
else:
# 执行函数
func = item[0] # send_message
param_list = item[1] # ['15131255089', '你好呀']
func(*param_list) # send_message(*['15131255089', '你好呀'])
情境二
def send_msg(mobile, content):
"""发送短信"""
pass
def send_email(to_email, subject, content):
"""发送图片"""
pass
def send_wechat(user_id, content):
"""发送微信"""
pass
func_list = [
{"name": send_msg, "params": {'mobile': "15131255089", "content": "你有新短消息"}},
{"name": send_email, "params": {'to_email': "wupeiqi@live.com", "subject": "报警消息", "content": "硬盘容量不够用了"}},
{"name": send_wechat, "params": {'user_id': 1, 'content': "约吗"}},
]
# {"name": send_msg, "params": {'mobile': "15131255089", "content": "你有新短消息"}},
for item in func_list:
func = item['name'] # send_msg
param_dict = item['params'] # {'mobile': "15131255089", "content": "你有新短消息"}
func(**param_dict) # send_msg(**{'mobile': "15131255089", "content": "你有新短消息"})
上述两个情境为了实现参数不一致的情况,可以在使用函数名构造字典的时候设置相应的参数来实现。
2、函数名赋值
- 将函数名赋值给其他变量,函数名其实就个变量,代指某函数;如果将函数名赋值给另外一个变量,则此变量也会代指该函数。
def func(a1,a2):
print(a1,a2)
func_list = [func,func,func]
func(11,22)
func_list[0](11,22)
func_list[1](33,44)
func_list[2](55,66)
- 对函数名重新赋值,如果将函数名修改为其他值,函数名便不再代指函数
def func(a1,a2):
print(a1,a2)
# 执行func函数
func(11,22)
# func重新赋值成一个字符串
func = "华青水上"
print(func)
注意:由于函数名被重新定义之后,就会变量新被定义的值,所以大家在自定义函数时,不要与python内置的函数同名,否则会覆盖内置函数的功能,
id,bin,hex,oct,len...
# len内置函数用于计算值得长度
v1 = len("武沛齐")
print(v1) # 3
# len重新定义成另外一个函数
def len(a1,a2):
return a1 + a2
# 以后执行len函数,只能按照重新定义的来使用
v3 = len(1,2)
print(v3)
3、函数名做参数和返回值
函数名其实就一个变量,代指某个函数,所以,他和其他的数据类型一样,也可以当做函数的参数和返回值 。
3.1 参数
def plus(num):
return num + 100
def handler(func):
res = func(10) # 110
msg = "执行func,并获取到的结果为:{}".format(res)
print(msg) # 执行func,并获取到的结果为:110
# 执行handler函数,将plus作为参数传递给handler的形式参数func
handler(plus)
3.2 返回值
def plus(num):
return num + 100
def handler():
print("执行handler函数")
return plus
result = handler()
data = result(20) # 120
print(data)
4、区分‘返回值’和‘print’
对于初学者的同学,很多人都对print和返回值分不清楚 。
这两个函数是完全不同的
- 在函数中使用print,只是用于在某个位置输出内容而已。
- 在函数中使用return,是为了将函数的执行结果返回给调用者,以便于后续其他操作。
def f1():
print(123)
def f2(arg):
ret = arg()
return ret
v1 = f2(f1)
print(v1)
# 输出
123
None
5、函数作用
作用域,可以理解为一块空间,这块空间的数据是可以共享的。通俗点来说,作用域就类似于一个房子,房子中的东西归里面的所有人共享,其他房子的人无法获取。
5.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()
5.2 全局和局部
Python中以函数为作用域,函数的作用域其实是一个局部作用域。
# 全局变量(变量名大写)
COUNTRY = "中国"
CITY_LIST = ["北京","上海","深圳"]
def download():
# 局部变量
url = "http://www.xxx.com"
...
def upload():
file_name = "rose.zip"
...
COUNTRY
和CITY_LIST
是在全局作用域中,全局作用域中创建的变量称之为【全局变量】,可以在全局作用域中被使用,也可以在其局部作用域中被使用。
download
和upload
函数内部维护的就是一个局部作用域,在各自函数内部创建变量称之为【局部变量】,且局部变量只能在此作用域中被使用。局部作用域中想使用某个变量时,寻找的顺序为:优先在局部作用域中寻找,如果没有则去上级作用域中寻找
。注意:全局变量一般都是大写。
示例1:在局部作用域中读取全局作用域的变量。
COUNTRY = "中国"
CITY_LIST = ["北京","上海","深圳"]
def download():
url = "http://www.xxx.com"
print(url)
print(COUNTRY)
print(CITY_LIST)
def upload():
file_name = "rose.zip"
print(file_name)
print(COUNTRY)
print(CITY_LIST)
print(COUNTRY)
print(CITY_LIST)
downlowd()
upload()
print(file_name) # 报错
print(url) # 报错
示例2:局部作用域和全局作用域变量同名,这算啥?
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]
"""
5.3 global关键字
默认情况下,在局部作用域对全局变量只能进行:读取和修改内部元素(可变类型),无法对全局变量进行重新赋值。
- 读取
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()
函数基础之函数、函数名、作用域总结到此结束, 如有不但指出欢迎指正!