Python 函数

作者:billy
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

函数介绍

提到函数,大家可能会想到数学函数吧。函数是数学非常重要的一个模块,贯穿整个数学。在 Pythoin 中,函数的应用非常广泛。在前面我们已经多次接触过函数,例如用于输出的 print() 函数,用于输入的 input() 函数,以及用于生成一系列整数的 range() 函数。这些都是 Python 内置的标准函数,可以直接使用。除了可以直接使用的标准函数外,Python 还支持自定义函数,即通过将一段有规律的、重复的代码定义为函数,来达到一次编写,多次使用的目的。使用函数可以提高代码的重复利用率。

函数的创建和调用

创建函数也称为定义函数,可以理解为创建一个具有某种用途的工具。使用 def 关键字实现,具体语法格式如下:

def functionName([parameterList]):
    ["comments"]
    [functionBody]

functionName:函数名称,在调用函数时使用;
parameterList:可选参数,用于指定向函数中传递的参数。如果有多个参数,各参数之间使用逗号 ‘,’ 分隔。如果不指定,则表示该函数没有参数,在调用时也不指定参数;
comments:可选参数,表示函数指定注释,注释的内容通常是说明该函数的功能、要传递的参数的作用等,可以为用户提供友好提示和帮助的内容;
functionBody:可选参数,用于指定函数体,即该函数被调用后执行的代码。如果函数有返回值,可以使用 return 语句返回;

示例:

def filterChar(string):     				# 定义函数 filterChar
    '''
    功能:过滤危险字符(如黑客),并将过滤后的结果输出
    about:要过滤的字符串
    返回值:无
    '''
    
    import re

    pattern = r'(黑客)|(抓包)|(监听)|(Trojan)'
    sub = re.sub(pattern, '@__@', string)
    print("函数内部:", sub)

about = "我是一名程序员,喜欢黑客方面的图书,想研究一下 Trojan"
filterChar(about)       				# 调用函数 filterChar
print("函数外部:", about)

上述例子的运行结果为:

函数内部: 我是一名程序员,喜欢@__@方面的图书,想研究一下 @__@
函数外部: 我是一名程序员,喜欢黑客方面的图书,想研究一下 Trojan

参数传递

  1. 形式参数与实际参数
    在定义一个函数时,函数名后面括号中的参数我们称之为 “形式参数”。而在调用一个函数时,函数名后面括号中的参数则是 “实际参数”。根据实际参数的类型不同,可以将实际参数的值传递给形式参数,或将实际参数的引用传递给形式参数。

当实际参数为不可变对象时,进行的是值传递;当实际参数为可变对象时,进行的是引用传递。值传递和引用传递的区别在于:值传递后,改变形式参数的值,实际参数的值不变;引用传递后,改变形式参数的值,实际参数的值也一同改变

示例1:

def demo(obj):
    print("原值:", obj)
    obj += obj

print("======值传递======")
mot = "唯有被追赶的时候,你才会真正的奔跑"
print("函数调用前: ", mot)
demo(mot)                  		 # 参数为不可变对象 - 字符串
print("函数调用后: ", mot)

print("======引用传递======")
list = ['绮梦', '冷伊一', '香凝', '黛兰']
print("函数调用前: ", list)
demo(list)				# 参数为可变对象 - 列表
print("函数调用后: ", list)

上述例子的运行结果为:

======值传递======
函数调用前:  唯有被追赶的时候,你才会真正的奔跑
原值: 唯有被追赶的时候,你才会真正的奔跑
函数调用后:  唯有被追赶的时候,你才会真正的奔跑
======引用传递======
函数调用前:  ['绮梦', '冷伊一', '香凝', '黛兰']
原值: ['绮梦', '冷伊一', '香凝', '黛兰']
函数调用后:  ['绮梦', '冷伊一', '香凝', '黛兰', '绮梦', '冷伊一', '香凝', '黛兰']

示例2:

def fun_bmi(person, height, weight):
    '''
    功能:根据身高体重计算 BMI 指数
    :param person: 姓名
    :param height: 身高,单位:米
    :param weight: 体重,单位:千克
    :return: 无
    '''

    print(person + "的身高:" + str(height) + '米,体重:' + str(weight) + '千克')
    bmi = weight/(height*height)
    print(person + "的 BMI 指数为:" + str(bmi))

    if bmi < 18.5:
        print("您的体重过轻 ~@_@~\n")
    if bmi >= 18.5 and bmi < 24.9:
        print("正常范围,注意保持 (-_-)\n")
    if bmi >= 24.9 and bmi < 29.9:
        print("您的体重过重 ~@_@~\n")
    if bmi >= 29.9:
        print("肥胖 ^@_@^\n")

fun_bmi("小明", 1.83, 60)
fun_bmi("小王", 1.75, 75)
fun_bmi("小孙", 1.70, 80)
fun_bmi("小李", 1.62, 80)

上述例子的运行结果为:

小明的身高:1.83米,体重:60千克
小明的 BMI 指数为:17.916330735465376
您的体重过轻 ~@_@~

小王的身高:1.75米,体重:75千克
小王的 BMI 指数为:24.489795918367346
正常范围,注意保持 (-_-)

小孙的身高:1.7米,体重:80千克
小孙的 BMI 指数为:27.68166089965398
您的体重过重 ~@_@~

小李的身高:1.62米,体重:80千克
小李的 BMI 指数为:30.48315805517451
肥胖 ^@_@^

注意:指定的实际参数的数量和位置必须与形式参数的数量和位置保持一致,否则将抛出 TypeError 异常

Python 中函数参数比其他语言(Java、C++)中的函数多了一个功能,叫关键字参数。关键字参数是指使用形式参数的名字来确定输入的参数值,通过该方式指定实际参数时,不再需要与形式参数的位置完全一致。例如,我们要调用上述例子中的函数 fun_bmi(person, height, weight)可以这样调用:
fun_bmi(height = 1.83, person = "小明", weight = 60)

  1. 为参数设置默认值
    调用函数时,如果没有指定某个参数,将抛出异常。为了解决这个问题,我们可以为参数设置默认值,即在定义函数时直接指定形式参数的默认值,这样,当没有传入参数时,则直接使用定义函数时设置的默认值。

示例:

def demo(obj = []):     	# 定义函数 demo 并为参数 obj 指定默认值
    print("obj 的值为: ", obj)
    obj.append(1)

demo()				# 连续调用两次,并且都不指定实际参数
demo()  			# 第二次的结果并不是我们想要的

上述例子的运行结果为:

obj 的值为:  []
obj 的值为:  [1]

定义函数时,为形式参数设置默认值要牢记一点:默认参数必须指向不可变对象
示例:

def demo(obj = None):
    if obj == None:
        obj = []
    print("obj 的值为: ", obj)
    obj.append(1)

demo()
demo()

上述例子的运行结果为:

obj 的值为:  []
obj 的值为:  []
  1. 可变参数
    在 Python 中,还可以定义可变参数。可变参数也称不定长参数,即传入函数中的实际参数可以是零个、一个、两个到任意个。定义可变参数时,主要有两种形式,一种是 *parameter,另一种是 **parameter。
  • *parameter 这种形式表示接收多个实际参数,并将其放到一个元组中

示例:

def print_coffee(*coffee):
    print("我喜欢的咖啡有:")
    for item in coffee:
        print(item, end=' ')
    print()

print_coffee("蓝山")
print_coffee("蓝山", "卡布奇洛", "摩卡", "麦斯威尔", "拿铁")

param = ['拿铁', '美式', '英式', '猫屎']
print_coffee(*param)	# 使用一个已存在的列表作为函数的可变参数,只需在列表名称前面加上 '*'

上述例子的运行结果为:

我喜欢的咖啡有:
蓝山 
我喜欢的咖啡有:
蓝山 卡布奇洛 摩卡 麦斯威尔 拿铁 
我喜欢的咖啡有:
拿铁 美式 英式 猫屎 
  • **parameter 这种形式表示接收多个类似关键字参数一样显示赋值的实际参数,并将其放到一个字典中

示例:

def print_sign(**sign):
    for key, value in sign.items():
        print("[" + key + "] 的星座是:" + value)
    print()

print_sign(绮梦="水瓶座", 冷伊一="射手座")
print_sign(香凝='双鱼座', 黛兰='双子座', 冷伊一='射手座')

dict = {'绮梦':'水瓶座', '冷伊一':'射手座', '香凝':'双鱼座'}
print_sign(**dict)

上述例子的运行结果为:

[绮梦] 的星座是:水瓶座
[冷伊一] 的星座是:射手座

[香凝] 的星座是:双鱼座
[黛兰] 的星座是:双子座
[冷伊一] 的星座是:射手座

[绮梦] 的星座是:水瓶座
[冷伊一] 的星座是:射手座
[香凝] 的星座是:双鱼座

返回值

在函数体中,可以使用 return 语句为函数指定返回值。该返回值可以是任意类型,并且无论 return 语句出现在函数的什么位置,只要得到执行,就会直接结束函数。

如果返回一个值,那么 result 中保存的就是返回的一个值,该值可以是任意类型。如果返回多个值,那么 result 中保存的是一个元组。

当函数中没有 return 语句,或者省略了 return 语句的参数时,将返回 None,即空值。

示例:

def fun_checkout(money):
    '''
    功能:计算商品合计金额并进行折扣处理
    :param monery: 保存商品金额的列表
    :return: 商品的合计金额和折扣后的金额
    '''

    money_old = sum(money)
    money_new = money_old
    if money_old >= 500 and money_old < 1000:
        money_new = '{:.2f}'.format(money_old * 0.9)
    elif money_old >= 1000 and money_old < 2000:
        money_new = '{:.2f}'.format(money_old * 0.8)
    elif money_old >= 2000 and money_old < 3000:
        money_new = '{:.2f}'.format(money_old * 0.7)
    elif money_old >= 3000:
        money_new = '{:.2f}'.format(money_old * 0.6)

    return money_old, money_new

print("------开始结算------")
list_money = []
while True:
    # 请不要输入非法的金额,否则会抛出异常
    inmoney = float(input("请输入商品金额(输入 0 表示输入完毕):"))
    if int(inmoney) == 0:
        break;
    else:
        list_money.append(inmoney)

money = fun_checkout(list_money)
print("合计金额为:", money[0], "应付金额为:", money[1])

上述例子的运行结果为:

------开始结算------
请输入商品金额(输入 0 表示输入完毕):256.2
请输入商品金额(输入 0 表示输入完毕):333.3
请输入商品金额(输入 0 表示输入完毕):578.24
请输入商品金额(输入 0 表示输入完毕):128.65
请输入商品金额(输入 0 表示输入完毕):0
合计金额为: 1296.39 应付金额为: 1037.11

变量的作用域

变量的作用域是指程序代码能够访问该变量的区域,如果超出区域,再访问时就会出现错误。在程序中,一般会根据变量的有效范围将变量分为局部变量和全局变量。

局部变量是指在函数内部定义并使用的变量,他只在函数内部有效。与局部变量对应,全局变量是能够作用于函数内外的变量,全局变量可以在函数外定义,也可以在函数内定义之后用 global 来修饰。

示例:

message = "我是一颗松树"

def demo1():
    message = "惊雷这通天修为,天塌地陷紫金锤"     # 局部变量
    print("函数体内:", message)

def demo2():
    global message
    message = "紫电说这玄真火焰,九天玄剑惊天变"    # 全局变量
    print("函数体内:", message)

print("函数体外:", message)
demo1()
print("函数体外:", message)
demo2()
print("函数体外:", message)

上述例子的运行结果为:

函数体外: 我是一颗松树
函数体内: 惊雷这通天修为,天塌地陷紫金锤
函数体外: 我是一颗松树
函数体内: 紫电说这玄真火焰,九天玄剑惊天变
函数体外: 紫电说这玄真火焰,九天玄剑惊天变

匿名函数

匿名函数(lambda)是指没有名字的函数,应用在需要一个函数但是又不想费神去命名这个函数的场合。通常情况下,这样的函数只使用一次。在 Python 中,使用 lambda 表达式创建匿名函数,其语法格式如下:
result = lambda [arg1 [,arg2,...,argn]]:expression
result:用于调用 lambda 表达式;
[arg1 [,arg2,…,argn]]:可选参数,用于指定要传递的参数列表,多个参数间使用逗号 ‘,’ 分隔;
expression:必选参数,用于指定一个实现具体功能的表达式。如果有参数,那么在该表达式中将应用这些参数;

示例:

import math

book = [('Python 从入门到放弃', 22.50, 120), ('零基础学 Python', 62.10, 89.80),
        ('Python 案例详解', 23.40, 36.00), ('Python 进阶之路', 22.50, 128)]

cal_circle = lambda r: math.pi * r * r          # 计算圆的面积
cal_rectangle = lambda w, h: w * 2 + h * 2      # 计算矩形的周长
sort = lambda x: (x[1], x[1] / x[2])            # 按照指定规则排序

print("半径为10的圆的面积是:", cal_circle(10))
print("长为10宽为8的矩形的周长是:", cal_rectangle(10, 8))
print("书本信息为:", book)
book.sort(key = sort)
print("排序之后的书本信息为:", book)

上述例子的运行结果为:

半径为10的圆的面积是: 314.1592653589793
长为10宽为8的矩形的周长是: 36
书本信息为: [('Python 从入门到放弃', 22.5, 120), ('零基础学 Python', 62.1, 89.8), ('Python 案例详解', 23.4, 36.0), ('Python 进阶之路', 22.5, 128)]
排序之后的书本信息为: [('Python 进阶之路', 22.5, 128), ('Python 从入门到放弃', 22.5, 120), ('Python 案例详解', 23.4, 36.0), ('零基础学 Python', 62.1, 89.8)]

你可能感兴趣的:(Python)