Python编程的函数—自定义函数

函数的定义

在Python中,自定义函数需要遵循一些规则和最佳实践。以下是一些关于Python中自定义函数的规则:

  1. 命名规则
  • 函数名应该是描述性的,用小写字母和下划线分隔单词(snake_case)。
  • 避免使用Python内置函数名或关键字作为函数名。
  1. 参数
  • 函数可以有零个或多个参数,通过参数列表传递给函数。
  • 可以定义默认参数值,这样调用函数时可不传递该参数。
  • 可以使用*args**kwargs处理可变数量的位置参数和关键字参数。
  1. 文档字符串
  • 应该为函数添加文档字符串(docstring),用于描述函数的目的、参数和返回值等信息。
  • 文档字符串应该放在函数定义的第一行。
  1. 代码块
  • 函数体内部的代码应该缩进,通常是四个空格或一个制表符。
  • 使用合适的空格和换行来提高代码的可读性。
  1. 返回值
  • 可以使用return语句从函数中返回值。
  • 如果没有return语句,则函数将默认返回None
  1. 可见性
  • 函数内部定义的变量默认是局部变量,只在函数内部可见。
  • 全局变量可以在函数内部访问,但如果要修改全局变量的值,需要使用global关键字声明。
  1. 函数调用
  • 在定义之后才能调用函数,否则会引发NameError
  • 函数可以作为其他函数的参数传递。
  1. 函数的嵌套
  • 可以在函数内部定义其他函数,形成嵌套函数结构。

遵循这些规则和最佳实践有助于编写清晰、易读且功能良好的自定义函数。

调用自定义函数

自定义函数后,就可以调用函数。举例说明,示例代码如下:

def myprint():  # 自定义函数,实现输出 "Hello, Python, 您好!“
    print('Hello, Python, 您好! ')

def myarea(x1, x2):  # 自定义函数,实现三角形的面积计算
    return 1/2*x1*x2

myprint()   # 调用自定义函数myprint()
print()
# 调用自定义函数myarea()
w = int(input('请输入三角形的底:'))
h = int(input('请输入三角形的高:'))
print('三角形的底 =', w, ' 三角形的高 =', h, ' 三角形的面积 =', myarea(w,h))

运行结果如下:

Hello, Python, 您好! 

请输入三角形的底:7
请输入三角形的高:10
三角形的底 = 7  三角形的高 = 10  三角形的面积 = 35.0

函数的参数传递

在Python中,函数的参数传递可以通过以下几种方式进行:

  1. 位置参数:按照定义时的顺序依次传递参数。示例:
def greet(name, message):
    print(f"Hello, {name}! {message}")

greet("Alice", "How are you?")
  1. 关键字参数:通过参数名来匹配传递的值,无需考虑参数的位置。示例:
greet(message="Nice to meet you!", name="Bob")
  1. 默认参数:在函数定义时为参数指定默认值,调用函数时如果未提供该参数,则使用默认值。示例:
def greet(name, message="Welcome"):
    print(f"Hello, {name}! {message}")

greet("Charlie")  # 输出: Hello, Charlie! Welcome
  1. 可变数量参数
  • *args用于接收不定数量的位置参数,以元组形式传递。
  • **kwargs用于接收不定数量的关键字参数,以字典形式传递。
    示例:
def calculate_sum(*args):
    total = sum(args)
    return total

result = calculate_sum(1, 2, 3, 4)  # args为(1, 2, 3, 4)
  1. 解包参数:将一个列表或元组解包成独立的元素传递给函数。示例:
numbers = [2, 4, 6]
print(*numbers)  # 输出: 2 4 6

通过这些方法,您可以以不同的方式传递参数给函数,从而方便地调用和操作函数。

匿名函数

所谓匿名,就是不再使用def语句这样标准的形式定义一个函数。在Python中,匿名函数(lambda函数)是一种简洁的方式来创建小型、临时的函数。匿名函数使用lambda关键字定义,通常用于需要一个简单函数的地方。以下是匿名函数的基本语法和一些使用示例:

基本语法:

lambda arguments: expression
  • lambda:关键字表示定义匿名函数。
  • arguments:函数的参数列表。
  • expression:函数体内的表达式,用于计算并返回结果。

使用示例:

  1. 单个参数的匿名函数
square = lambda x: x * x
print(square(5))  # 输出: 25
  1. 多个参数的匿名函数
add = lambda a, b: a + b
print(add(3, 4))  # 输出: 7
  1. 结合内置函数
numbers = [1, 2, 3, 4, 5]
squared_numbers = list(map(lambda x: x*x, numbers))
print(squared_numbers)  # 输出: [1, 4, 9, 16, 25]
  1. 作为排序函数的key参数
students = [('Alice', 22), ('Bob', 19), ('Charlie', 25)]
students.sort(key=lambda x: x[1])
print(students)  # 按年龄升序排列

匿名函数通常用于简单的操作或作为其他函数的参数传递,能够提高代码的简洁性和可读性。然而,由于匿名函数无法包含复杂的逻辑或多行代码,所以最好在需要较复杂逻辑的情况下使用普通的命名函数。

递归函数

递归函数是在定义中调用自身的函数。在Python中,可以使用递归来解决那些可以被分解为相同问题的子问题的情况。下面是一个简单的示例说明递归函数的概念:

示例:计算阶乘

def factorial(n):
    if n == 0:
        return 1
    else:
        return n * factorial(n - 1)

# 调用递归函数计算阶乘
result = factorial(5)
print("Factorial of 5 is:", result)  # 输出: Factorial of 5 is: 120

在这个示例中:

  • factorial函数计算给定数字n的阶乘。
  • n为0时,返回1(基本情况)。
  • 否则,将nfactorial(n-1)的结果相乘并返回。

递归函数的要点:

  1. 基本情况:递归函数必须有基本情况,以便结束递归过程。
  2. 递归调用:函数内部通过调用自身来解决规模更小的子问题。
  3. 递归深度:如果递归深度太大,可能会导致栈溢出。Python默认支持最大递归深度限制。

递归函数通常用于处理树结构、分治法或需要重复应用相同操作的问题。然而,应谨慎使用递归,因为它可能会导致性能问题和代码可读性降低。

实例:计算一个数为两个质数之和

质数又称素数,是指整数在一个大于1的自然数中,除了1和此整数自身,无法被其他自然数整除的数。也就是说,只有两个正因数(1和自己)的自然数即为质数。

示例代码如下:

# 定义一个判断是否是质数的函数
def myprime(n):
    isprime = 1
    for i in range(2, int(n/2)+1):
        if n % i == 0:
            isprime = 0
            break
    return isprime


flag = 0
n = int(input('请输入一个正整数:'))
for i in range(2, int(n/2)+1):
  	# 检测判断
    if myprime(i) == 1:    
      	# 递归调用myprime()函数
        if myprime(n-i) == 1:
            print(n, '=',i,'+', n - i)
            flag = 1
if flag == 0:
    print(n, '不能分解为两个质数')

运行结果如下:

请输入一个正整数:72
72 = 5 + 67
72 = 11 + 61
72 = 13 + 59
72 = 19 + 53
72 = 29 + 43
72 = 31 + 41
请输入一个正整数:17
17 不能分解为两个质数

实例:利用内置函数实现小学四则运算

首先导入random标准库,然后定义一个生成数学题的函数,返回运算题型和正确的答案。接着while循环,进行循环出题,答案输入666程序结束。

import random

# 定义一个生成数学运算题的函数
def generate_math_problem():
    # 生成两个随机整数作为运算数
    num1 = random.randint(1, 100)
    num2 = random.randint(1, 100)

    # 随机选择一个运算符
    operator = random.choice(['+', '-', '*', '/'])

    # 根据运算符计算结果
    if operator == '+':
        result = num1 + num2
    elif operator == '-':
        result = num1 - num2
    elif operator == '*':
        result = num1 * num2
    else:
        result = num1 / num2  # 注意:这里可能会有除不尽的情况

    # 构建问题字符串
    problem = f"{num1} {operator} {num2} = ?"

    return problem, result

print('小学四则运算测试(输入666结束)')
# 标志变量
flag = True
# 初始化一个计数变量,显示第几道题
n = 1
while flag:
    # 生成一个数学问题和答案
    math_problem, answer = generate_math_problem()

    print(f"请解答第{n}这道数学题:")
    print(math_problem)

    user_answer = float(input("请输入你的答案: "))

    if user_answer == answer:
        print("正确!")
    elif user_answer != 666:
        print("你的答案不正确! 正确的答案是:", answer)
    if user_answer == 666:
        flag = False
    n += 1

运行结果如下:

小学四则运算测试(输入666结束)
请解答第1这道数学题:
47 + 98 = ?
请输入你的答案: 104
你的答案不正确! 正确的答案是: 145
请解答第2这道数学题:
90 * 76 = ?
请输入你的答案: 831
你的答案不正确! 正确的答案是: 6840
请解答第3这道数学题:
34 + 68 = ?
请输入你的答案: 102
正确!
请解答第4这道数学题:
51 * 86 = ?
请输入你的答案: 48881
你的答案不正确! 正确的答案是: 4386
请解答第5这道数学题:
48 * 21 = ?
请输入你的答案: 1008
正确!
请解答第6这道数学题:
22 / 41 = ?
请输入你的答案: 666
  • generate_math_problem函数用于生成一个包含随机运算数和运算符的数学问题,并计算出正确的答案。
  • 我们打印出生成的数学问题,并提示用户输入答案。
  • 用户输入答案后,程序会检查答案是否正确,并给出相应的回复。

您可以运行这段代码进行小学四则运算练习。每次运行都会生成一个新的数学问题,用户需要输入答案并获取相应的反馈。


我的个人公众号

Python编程的函数—自定义函数_匿名函数