Python函数

目录

一、函数是什么?

二、函数定义

三、函数调用

四、参数类型

1.位置参数

2.默认参数

3.关键字参数

4.可变参数

五、返回值

六、递归函数

七、匿名函数

1.语法结构

2.形式

(1)无参,无返回值

(2)无参,有返回值

(3)有参,有返回值

(4)有参,无返回值

3.高阶函数

(1)sorted函数

(2)map函数

(3)filter函数

八、变量作用域

1.局部变量

2.全局变量

3.修改全局变量

4.在嵌套函数中修改外层变量

5.LEGB规则

九、闭包与装饰器

1.闭包

2.装饰器

2.1.语法结构

2.2.案例

2.2.1.时间开销

2.2.2.权限校验

2.2.3.日志记录

总结


一、函数是什么?

函数是一段封装了特定功能可重复执行的的代码块。

二、函数定义

用def定义一个函数,具体的语法结构如下:

def 函数名(参数1, 参数2, ...):
    """文档字符串(可选)"""
    函数体
    return 返回值  # 可选

def:声明一个函数。

函数名:给函数起的一个名字。

注释:针对下面的代码块所给予的解释性说明。

函数体:实现函数功能的一段代码块。

return:返回函数的结果,没有则返回None。

注意:一旦执行力return,就代表着函数执行结束,后续代码块也就不会执行。

三、函数调用

当定义好一个函数后,需要通过调用来实现这一代码块的功能。下面是一个打招呼的问候函数,具体代码示例如下:

def greet(name):
    """向指定的人问好"""
    return f"Hello, {name}!"
#调用函数,实现其功能。
message = greet("Alice")
print(message)  # 输出: Hello, Alice!

调用函数的格式是:函数名()。函数有返回值的,通过print()打印出函数的返回值。

四、参数类型

1.位置参数

位置参数必须按照位置的顺序赋值,不能忽略任何一个参数。

def greet(name, greeting):
    print(f"{greeting}, {name}!")

greet("Alice", "Hello")  # 正确:按顺序传参
greet("Hello", "Alice")  # 错误:顺序不对,逻辑错误

2.默认参数

定义函数时,在小括号内指定某个参数,给其赋给一个默认值。

def greet(name, greeting="Hello"):
    print(f"{greeting}, {name}!")

greet("Alice")          # 使用默认值 "Hello"
greet("Bob", "Hi")      # 覆盖默认值

两点注意:如果传入有实参,则使用实参;默认参数必须放在位置参数之后,否则会报错。

3.关键字参数

在传入实参的括号内,以“参数=值”的形式传参,顺序可以打乱;有默认参数时,会覆盖默认参数,使用关键字参数。

def greet(name, greeting):
    print(f"{greeting}, {name}!")

greet(greeting="Hi", name="Alice")  # 关键字传参,顺序不影响

4.可变参数

(1)元组类型(*args

可以接收任意数量的位置参数,以元组的形式保存起来。

def sum_numbers(*args):
    return sum(args)

print(sum_numbers(1, 2, 3))  # 6
print(sum_numbers(1, 2, 3, 4, 5))  # 15

(2)字典类型(**kwargs

可以接收任意数量的关键字参数(参数=值的形式),以字典的形式保存起来。重要的是二者的先后顺序是:按照*args在前,**kwargs在后的先后顺序排列。

def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="Alice", age=25, city="New York")

#输出:
#name: Alice
#age: 25
#city: New York

五、返回值

三点描述:

  • 1.返回值通过return返回。
  • 2.可以返回多个值,实际上是返回一个元组。
  • 3.函数中return,或者return没有值,都是返回空值None。
def min_max(numbers):
    return min(numbers), max(numbers)
print(min_max([3, 1, 4, 1, 5, 9]))#输出:(1, 9)

上述函数的输出结果是元组,因为返回的有多个值。

六、递归函数

递归函数是指在函数定义中调用自身的函数,是解决某些问题的强大工具。递归通过将问题分解为更小的同类子问题来工作。

经典案例:斐波那契数列

def fibonacci(n):
    if n == 1 or n == 2:           # 基线条件
        return 1
    else:                # 递归条件
        return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(7))  # 输出: 13

提出的几点注意:

  1. 自己调用自己
  2. 需要有出口
  3. 递归效率很低,一般不使用递归。

如果想查看或者修改递归深度,可以使用sys模块。

from sys import getrecursionlimit, setrecursionlimit

print(getrecursionlimit())#1000
setrecursionlimit(1200)
print(getrecursionlimit())#1200

七、匿名函数

1.语法结构

lambda 参数 : 函数体

lambda:定义匿名函数的关键字

参数:可以有多个,用逗号分隔

函数体:只能是一个表达式(不能是语句)

例如:计算两个数的和,add()是一个函数,通过print()返回值。

# 定义一个计算两数之和的lambda函数
add = lambda a, b: a + b
print(add(3, 4))  # 输出: 7

2.形式

(1)无参,无返回值

my_fun1 = lambda: print("上课铃响了")
my_fun1()

my_fun1这个函数没有参数,也没有返回值,输出的结果是“上课铃响了”。

(2)无参,有返回值

myfun3 = lambda : 15
print(myfun3())

my_fun2这个函数没有参数,但是有返回值,将常量15返回出来了。

(3)有参,有返回值

a = [1, 2, 3, 4, 5]
my_fun2 = lambda a: [i*i for i in a]
r = my_fun2(a)
print(r)

my_fun3这个函数有参数,有返回值,将参数a这个列表传入匿名函数,结果可以得到新的列表。

(4)有参,无返回值

myfun4 = lambda x: print(f"数字是{x}")
myfun4(9)

my_fun4这个函数有参数,没有返回值,将参数x=9传入匿名函数,通过print()打印结果输出9。

3.高阶函数

(1)sorted函数

sorted( ):对可迭代对象进行排序并返回新列表,支持自定义排序规则。

结构:sorted(可迭代对象, key=匿名函数)

students = [
    {"name": "Alice", "age": 20},
    {"name": "Bob", "age": 18},
    {"name": "Charlie", "age": 22}
]
sorted_student = sorted(students, key=lambda x: x["age"])
print(sorted_student)

这个案例的功能是对字典排序,其中用匿名函数指出使用“age”关键字进行排序。

(2)map函数

map( ):将函数应用于可迭代对象的每个元素,返回包含结果的迭代器。

结构:map(匿名函数,可迭代对象)

l = [1, 5, 7, 3, 9]
maped_l = map(lambda x: x+1, l)
print(type(maped_l))# <class 'map'> map对象
for i in maped_l:
    print(i)

本案例map函数的数据类型是map类性,需要进一步的遍历得出每一个结果。

(3)filter函数

filter( ) : 用指定函数过滤可迭代对象,返回满足条件的元素组成的迭代器。

结构:filter(匿名函数, 可迭代对象)

students = [
    {"name": "Alice", "age": 20},
    {"name": "Bob", "age": 18},
    {"name": "Charlie", "age": 22}
]
filtered_student = filter(lambda x: x["age"] == 18, students)
print(type(filtered_student))# <class 'filter'>filter对象
for j in filtered_student:
     print(j)

filter()函数的类型是filter,其结果也需要进一步的遍历。本例功能是指出age=18,遍历出其对应的字典。

八、变量作用域

1.局部变量

函数内部定义的变量,仅在函数内部可见

def my_func():
    x = 10  # 局部变量
    print(x)

my_func()  # 输出: 10
print(x)   # 报错: NameError

2.全局变量

在模块级别定义的变量,整个模块都可见

y = 20  # 全局变量

def my_func():
    print(y)  # 可以访问全局变量

my_func()  # 输出: 20
print(y)   # 输出: 20

3.修改全局变量

在需要修改全局变量时显式使用 global 关键字

count = 0

def increment():
    global count  # 声明使用全局变量
    count += 1

increment()
print(count)  # 输出: 1

4.在嵌套函数中修改外层变量

在嵌套函数中修改外层变量时使用 nonlocal 关键字

def outer():
    x = "outer"
    
    def inner():
        nonlocal x  # 声明使用外层函数的变量
        x = "inner"
        print(x)    # 输出: inner
    
    inner()
    print(x)        # 输出: inner 

outer()

5.LEGB规则

  1. 局部作用域(Local) - 在函数内部定义的变量

  2. 闭包函数外的函数作用域(Enclosing) - 嵌套函数中的外层函数变量

  3. 全局作用域(Global) - 在模块级别定义的变量

  4. 内置作用域(Built-in) - Python内置的变量(如printlen等)

九、闭包与装饰器

1.闭包

闭包是指在一个内部函数中访问其外部函数作用域中的变量,即使外部函数已经执行完毕。

三要素:

  •   1.外部函数嵌套内部函数
  •   2.外部函数返回内部函数
  •   3.内部函数可以访问保存外部函数的局部变量。
def outer_fun():
    x = 20
    def inner_fun():
        nonlocal x
        x += 10
        y = 10
        print(x, y)
    return inner_fun # 注意此处是返回函数对象,而不是返回整个函数。

r = outer_fun()
# print(r)# <function outer_fun.<locals>.inner_fun at 0x000001CBEB0A3BA0>,说明r是函数
r()# 30 10
r()# 40 10
r()# 50 10 内部函数可以访问保存外部函数的局部变量

2.装饰器

装饰器是一种特殊类型的闭包,用于修改或增强函数的行为而不改变其原始定义。

2.1.语法结构

闭包+@语法

2.2.案例

2.2.1.时间开销

编写装饰器统计使用冒泡排序与选择排序时间开销

import  random, time

def time_cost(fun):
    def calc():
        start = time.time()
        fun()
        end = time.time()
        print(f"{fun.__name__}累计耗时{end - start}")
    return calc

@time_cost
def sort1():
    l = [random.randint(1, 100) for i in range(100)]
    l.sort()
    print(l)
sort1()

@time_cost
def sort2():
    l = [random.randint(1, 100) for i in range(100)]
    t = sorted(l)
    print(t)
sort2()

@time_cost
def sort3():
    l = [random.randint(1, 100) for i in range(100)]
    for i in range(1, len(l)):
        for j in range(0, len(l)-i):
            if  l[j] > l[j+1]:
                l[j], l[j+1] = l[j+1], l[j]
    print(l)
sort3()

@time_cost
def sort4():
    l = [random.randint(1, 100) for i in range(100)]
    for i in range(len(l) - 1):
        max_index = i
        for j in range(i+1, len(l)):
            if l[j] < l[max_index]:
                max_index = j
        l[max_index], l[i] = l[i], l[max_index]
    print(l)
sort4()
2.2.2.权限校验

下面是登录界面的权限校验。

from functools import wraps

user = None
def login(fun):
    @wraps(fun)
    def check():
        global user
        if user is not None:
            fun()
        else:
            username = input("请输入用户名:")
            password = input("请输入密码:")
            if username == "user" and password == "123456":
                user = username
                fun()
            else:
                print("未成功登陆,请重新验证!")
    return check

def my_main():
    print("欢迎来到主页")
my_main()

@login
def my_login():
    print("欢迎来到个人中心")
my_login()

@login
def my_cart():
    print("欢迎来到购物车")
my_cart()
2.2.3.日志记录

通过装饰器,对功能函数的运行时间、参数、函数名以及返回值进行记录。

from datetime import datetime

def my_log(fun):
    def inner_log(*args):
        t = fun(*args)
        with open("record.log", "a", encoding="utf8") as f:
            msg = f"时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} 函数名:{fun.__name__} 参数:{args} 返回值:{t}"
            f.write(f"{msg}\n")
        return t
    return inner_log

@my_log
def get_sum(a, b):
    total = a + b
    return total


print(get_sum(5, 7))

总结

函数是编程中用于封装特定功能的可重用代码块,通过定义和调用来实现模块化编程。定义函数使用`def`关键字,后接函数名、参数列表和冒号,函数体需缩进。调用函数时通过函数名加括号传入实际参数即可执行函数体代码。参数分为位置参数、关键字参数、默认参数和可变参数(`*args`和`**kwargs`),灵活适应不同调用需求。函数通过`return`返回值,若无返回则默认`None`。递归函数通过调用自身解决问题,需设置终止条件防止无限递归。匿名函数(`lambda`)用于简化小型函数定义,格式为`lambda 参数:表达式`。变量作用域分局部(函数内)和全局(函数外),局部变量优先,全局变量需用`global`声明修改。闭包是嵌套函数中内层函数引用外层变量,常用于保存状态;装饰器基于闭包实现,通过`@`语法通常在不修改原函数代码前提下扩展功能,如日志、计时等。这些特性共同构成Python函数编程的核心,提升代码的复用性、可读性和灵活性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值