Python基础——函数进阶之函数、函数名、作用域

函数名其实就是一个变量,这个变量只不过代指的函数而已。

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"
    ...

COUNTRYCITY_LIST是在全局作用域中,全局作用域中创建的变量称之为【全局变量】,可以在全局作用域中被使用,也可以在其局部作用域中被使用。

downloadupload函数内部维护的就是一个局部作用域,在各自函数内部创建变量称之为【局部变量】,且局部变量只能在此作用域中被使用。局部作用域中想使用某个变量时,寻找的顺序为优先在局部作用域中寻找,如果没有则去上级作用域中寻找

注意:全局变量一般都是大写。

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

函数基础之函数、函数名、作用域总结到此结束, 如有不但指出欢迎指正!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值