当前位置: 首页 > news >正文

python-14-函数详解(定义、参数、返回值、高级函数、偏函数、装饰器)

python函数详解(定义、参数、返回值、高级函数、偏函数、装饰器)

一.说明

这是python中的基础系列中的关于函数部分,来开始我们今天日拱一卒!对python函数部分进行详细整理和学习。

二.定义

  1. 在Python中,函数是通过 def 关键字来定义函数;

  2. 函数定义的结构如下

    def function_name(parameters):"""函数的文档字符串,可选"""# 函数体return value  # 可选
    
  3. function_name 是函数的名称,遵循标识符命名规则

  4. parameters 是函数的输入参数,可以有多个,也可以没有

  5. 函数体是实现具体功能的代码块

  6. return语句用于返回结果,若没有,则默认返回 None

三.特性

  1. 封装性:函数将特定功能的代码封装在一起,便于复用
  2. 可读性:通过函数名称和文档字符串,提升代码的可读性
  3. 模块化:可以将复杂的任务分解为多个简单的函数,便于管理和调试

四.函数参数

在各类语言中函数参数一般都分为形参和实参!这个概念,很多时候被忽略,因为就算不理解这一概念,也照样使用,那么什么是形参和实参,很简单,让我来概括。

形参:函数定义是的参数就是形参;

实参:函数调用时传入的参数就是实参;

就这么简单?在python中这一概念可不这么简单!!让我来细细整理,这是核心!!

1.位置参数

参数的定义和调用,按顺序传递

def greet(name):print(f"Hello, {name}!")
greet("Alice")  # 输出: Hello, Alice!
2.关键字参数

调用时,通过参数名称传递

def greet(name, age):print(f"{name} is {age} years old.")
greet(age=30, name="Bob")  # 输出: Bob is 30 years old.
3.默认参数

可以为参数指定默认值,注意,这里又有一个隐藏概念!指定默认值的行参必须放在未指定默认值的形参后面

def greet(name, greeting="Hello"):print(f"{greeting}, {name}!")
greet("Alice")  # 输出: Hello, Alice!########
def greet(greeting="Hello",name):print(f"{greeting}, {name}!")   #报错
greet("Alice")  
4.可变参数

使用 *args**kwargs 处理不定数量的参数

*args:传入参数被当作元组处理

**kwargs:传入参数被当作字典处理

def summarize(*args):return sum(args)def show_info(**kwargs):for key, value in kwargs.items():print(f"{key}: {value}")summarize(1, 2, 3)  # 输出: 6
show_info(name="Alice", age=30)  # 输出: name: Alice, age: 30

可变参数 是不是觉得很简单,一看就会?等会一练就废!大家看看下面的代码,输出结果是什么?

def demo(a,b,*args):print("a:",a)print("b:",b)print("arg:",args)
demo(1,2,3)
demo(1,2,3,4,5)def demo1(a,**args):print("a",a)print("args",args)
demo1(1,name='bob',age=33)def demo3(a,b,c=0,*args,**kwargs):print("a:",a)print("b:",b)print("c:",c)print("arg:",args)print("kwargs:",kwargs)demo3(1,2,k=3)
demo3(1,2,3,4,5)
demo3(1,b=2,c=3,d=4)
demo3(*(1,2,3),**{'age':4}) def custom_function(a, b, c=0, *args, **kwargs):print("a:", a)print("b:", b)print("c:", c)print("args:", args)print("kwargs:", kwargs)custom_function(1, 2)                             
custom_function(3, 4, 5, 6, 7, name="Alice")    
5.函数参数默认值计算方式

先看一下这个案例:

def test(a=[]):a.append('end')print(a)
test([1,2,3]) #[1,2,3,'end']
test()  #['end']
test()  #['end','end']
test([4,5,6]) #[4,5,6,'end']

请问为啥会出现[‘end’,‘end’]?为什么会出现这种情况!

这个与python语言特性和 python中函数的参数默认值实现逻辑有关!

函数参数的默认值只在函数定义时计算一次,而不是每次调用时,这意味着如果你使用可变对象(如列表或字典)作为默认值,它会在后续调用中保持修改状态。

好那么还有一个疑问,如何避免这个问题?

def test(a=None):if a is None:a = []a.append('end')print(a)

五.返回值

  1. return 语句返回 函数的计算结果,也可以没有return 默认返回 None

    def demo1():passa = demo1()
    print(a)   #None
    
  2. return 可以返回一个值,也可返回多个值,当返回多个值 那么返回的是一个元组

    def demo1():return 1,2,3,4a = demo1()
    print(a)   #(1, 2, 3, 4)
    

六.文档字符串

函数的文档字符串,其实就是函数的帮助文档,包含函数的基础信息、函数的功能简介、函数的形参类型,使用等

文档字符串规则:

  1. 必须在函数首行定义文档字符串;

  2. 使用三个引号 注解;

#Google 风格
def multiply(x, y):"""Multiply two numbers.Args:x (int or float): The first number.y (int or float): The second number.Returns:int or float: The product of x and y."""return x * y#NumPy 风格
def divide(x, y):"""Divide x by y.Parameters----------x : int or floatThe numerator.y : int or floatThe denominator.Returns-------floatThe result of x divided by y."""return x / y

七.函数的类型

  1. 空函数

    函数体不完成任何功能,只有一个pass

    def demo1():passa = demo1()
    print(a)   #None
    
  2. 匿名函数

不再使用def 函数名()这种形式定义函数,而是使用lambda来创建匿名函数

lambda函数:

  1. lambda 函数只能包含一个表达式,即只有一行,不能包含多个语句或复杂逻辑

  2. lambda函数是匿名的,但可以将其赋值给一个变量,以便后续使用

    add = lambda x, y: x + y
    print(add(3, 5))  # 输出: 8#过滤
    numbers = [1, 2, 3, 4, 5, 6]
    even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
    print(even_numbers)  # 输出: [2, 4, 6]
    #映射
    squared_numbers = list(map(lambda x: x ** 2, numbers))
    print(squared_numbers)  # 输出: [1, 4, 9, 16, 25, 36]
    #排序
    people = [{'name': 'Alice', 'age': 30},{'name': 'Bob', 'age': 25},{'name': 'Charlie', 'age': 35}
    ]# 按年龄排序
    sorted_people = sorted(people, key=lambda person: person['age'])
    print(sorted_people)
    # 输出: [{'name': 'Bob', 'age': 25}, {'name': 'Alice', 'age': 30}, {'name': 'Charlie', 'age': 35}]

八.高级函数

高阶函数是指可以接受其他函数作为参数或返回一个函数的函数

def high_order_function(func):return func(10)def square(x):return x * xresult = high_order_function(square)  # 输出: 100
print(result)

九.偏函数

偏函数(Partial Function)是指通过固定一个函数的部分参数来创建一个新的函数。在Python中,可以使用 functools 模块中的 partial() 函数来实现偏函数。这种方式特别有用,可以使函数更加灵活和简洁。

from functools import partialdef calculate_price(original_price, discount_rate):"""计算折后价格"""return original_price * (1 - discount_rate)# 固定折扣率为 20%
calculate_discounted_price = partial(calculate_price, discount_rate=0.20)# 示例商品价格
prices = [100, 200, 300, 400]# 计算折后价格
discounted_prices = [calculate_discounted_price(price) for price in prices]# 打印结果
for original, discounted in zip(prices, discounted_prices):print(f"原价: {original},折后价: {discounted:.2f}")'''
原价: 100,折后价: 80.00
原价: 200,折后价: 160.00
原价: 300,折后价: 240.00
原价: 400,折后价: 320.00
'''

十.装饰器

这个为函数这一概念中的重点的重点,在现实开发中使用场景非常多,想学习python必须掌握装饰器,这一概念!不然根本不算入门!

当然学习函数装饰器也很简单,静下来,看完慢慢缕一缕!

  1. 概念

    装饰器本质上是一个函数,它接受另一个函数作为参数,并返回一个新的函数。这个新的函数通常是在原始函数的基础上,增加了一些额外的功能。

  2. 装饰器语法

    装饰器使用 @decorator_name 语法来应用于函数。下面是一个简单的示例:

    def my_decorator(func):def wrapper():print("Something is happening before the function is called.")func()print("Something is happening after the function is called.")return wrapper
    @my_decorator
    def say_hello():print("Hello!")
    #调用
    say_hellosay_hello()'''
    输出:Something is happening before the function is called.
    Hello!
    Something is happening after the function is called.
    '''
    1. 定义装饰器
      • my_decorator 是装饰器,它接受一个函数 func 作为参数。
      • wrapper 是内部函数,执行装饰器的额外逻辑,调用原始函数 func
    2. 使用装饰器
      • @my_decoratorsay_hello 函数传递给 my_decorator
      • say_hello 实际上变成了 wrapper 函数。
    3. 调用函数
      • 当你调用 say_hello() 时,实际上是在调用 wrapper()
  3. 带参数装饰器

    如果你想要装饰器接受参数,可以通过定义一个装饰器工厂来实现:

    def repeat(num_times):def decorator_repeat(func):def wrapper(*args, **kwargs):for _ in range(num_times):func(*args, **kwargs)return wrapperreturn decorator_repeat
    @repeat(3)
    def greet(name): print(f"Hello, {name}!")
    greet("Alice")'''
    输出:
    Hello, Alice!
    Hello, Alice!
    Hello, Alice!
    '''
  4. 使用场景

    1. 日志记录:在函数执行前后记录日志
    2. 权限验证:检查用户是否有权调用某个函数
    3. 缓存:存储函数结果以减少计算时间
  5. 保持原函数的元数据

    使用 functools.wraps 可以确保装饰器不会丢失原函数的元数据(如名称和文档字符串)

    from functools import wraps
    def my_decorator(func): @wraps(func) def wrapper(): print("Before") func() print("After") return wrapper
    
  6. 总结

    装饰器是一个非常强大的特性,可以在不修改函数本身的情况下,增加或改变其行为。它们在许多框架和库中被广泛使用,例如 Flask 和 Django,常用于路由、请求处理和权限控制。。

    其实要掌握也很简单,照抄写法就行 主要是带参数的装饰器。。

十一.总结

其实函数还有一大模块,变量和作用域,这一概念需要单独提出来写,函数这一概念 重点注意 参数传递/调用/返回值/装饰器,特别是装饰器 这东西实在太强大了,相比其他语言想要实现这一功能就要复杂很多!

创作整理不易,请大家多多关注 多多点赞,有写的不对的地方欢迎大家补充,我来整理,再次感谢!


http://www.mrgr.cn/news/64565.html

相关文章:

  • 如何选择最适合的消息队列?详解 Kafka、RocketMQ、RabbitMQ 的使用场景
  • Spring Boot代理问题
  • 【spark的集群模式搭建】spark集群之Yarn集群模式搭建(清晰明了的搭建流程)
  • 【位域打包CAN报文】通过位域打包CAN报文的数据,实现精确控制每个(CAN信号)字段
  • 基于SSM+小程序的高校寻物平台管理系统(失物1)
  • CentOS下载ISO镜像的方法
  • 【JAVA毕业设计】基于Vue和SpringBoot的甘肃非物质文化网站
  • java项目之微服务在线教育系统设计与实现(springcloud)
  • 服务器虚拟化:构建高效弹性IT环境的基础
  • MYSQL学习笔记
  • 在Docker中安装和配置Nginx
  • 【算法-选择排序】挑挑拣拣,排出顺序——选择排序入门
  • 教育数据知识图谱创建
  • 适用于 c++ 的 wxWidgets框架源码编译SDK-windows篇
  • 【微服务】Spring AI 使用详解
  • 中国书画、
  • AI写诗:自动版大唐宫体诗
  • distrobox install in ubuntu 22.04 / 在 ubuntu 22.04 上安装 distrobox (***) OK
  • Halcon区域分割之分水岭分割法
  • APP的设置页面,应该怎样尽可能减少用户的输入操作呢
  • Python 一维列表基础语法
  • HashMap的实现原理
  • 十四届蓝桥杯STEMA考试Python真题试卷第二套第二题
  • 【热门主题】000024 探索人工智能学习框架:开启智能未来之门
  • JDBC学习笔记
  • Maven随笔