python入门系列七(函数)

1.引言

到目前,我们其实对函数已经有一点概念了。比如前面使用过的输入函数input,打印函数print,刚刚操作文件的函数open等。当然,这些都是python给我们已经内置好的函数。本篇文章我们试图搞清楚函数的意义,以及如何自己去定义函数。

如果要给函数下一个定义的话,我们可以这么去描述,即函数是用于封装需要多次,或者说重复执行的代码片段,提高代码的可复用性。这即是函数存在的意义,当然作为面向对象编程语言,函数有更深层次的含义,它是我们组织代码的基本单元之一,于面向对象编程而言,它还起到封装操作的意义。

2.函数

2.1.定义函数

在python中,定义函数通过def关键字进行修饰,函数由函数名称,输入参数,返回值共同组成。具体语法结构:

python 复制代码
def 函数名称([输入参数]):
    函数体
    [return 返回值]

2.2.调用函数

定义函数,以及调用函数

python 复制代码
# 定义函数
def hello_fun(name):
    print(f"hello {name}!")
    return "ok"

# 调用函数
result = hello_fun("python")
print(result)

2.3.匿名函数

匿名函数是通过lambda表达式进行函数的定义和调用。基本语法:

python 复制代码
# 定义匿名函数
square = lambda x: x**2

#调用匿名函数
print(square(5)) 

2.4.高阶函数

python中,函数可以作为对象来使用,像这样:

python 复制代码
# 定义一个函数
def add(x):
    return x+x

# 调用函数
sum = add(1)
print(sum)

#函数作为对象来使用
add_2 = add
print(add_2(1))

将函数作为对象来使用有什么好处?解决了什么问题?答案常见场景下,用于配合高阶函数来使用,让代码更优雅简洁!

什么是高阶函数?可以接收函数作为参数传入的函数,叫做高阶函数。python典型的高阶函数有:map,filter,sorted,reduce

2.4.1.高阶函数map

map映射函数,示例:

python 复制代码
# 高阶函数map
list = [1,2,3,4,5,6]
for i in map(add,list):
    print(i)

将可迭代对象list中的每个值,作用于add函数,当然具体业务需求要做什么,取决于add函数怎么定义了。

2.4.2.高阶函数filter

filter过滤函数,示例:

python 复制代码
# filter 过滤函数
list = [1,2,3,4,5,6]
for i in filter(lambda x:x%2==0,list):
    print(i)

2.4.3.高阶函数sorted

sorted排序函数,示例:

python 复制代码
# sorted 排序函数
list = [1,2,3,4,5,6]
for i in sorted(list,key=lambda x:-x):
    print(i)

2.4.4.高阶函数reduce

累积求值函数reduce,函数:

python 复制代码
from functools import reduce
# reduce 累积求值函数
list = [1,2,3,4,5,6]
print(reduce(lambda x,y:x+y,list))

注意:reduce函数已经移入functools模块,使用要先导入。关于import知识后面会详细说明。

2.5.偏函数

python中偏函数,指的是可以用于将已有函数,和参数固化成为新的函数来使用。说概念有点绕,看一个示例就明白了:

python 复制代码
# 操作文件open函数,有太多参数了,又是mode,又是encoding,每次传值其实都是一样的。像这样
with open("hello.txt","r",encoding="utf-8") as f:
    #读取文件内容
    data = f.read()
    print(data)

有没有什么方法简化一下open函数的使用?可以这样:

python 复制代码
# 固化一下open函数及参数,方便使用
from functools import partial
my_open = partial(open,mode='r',encoding='utf-8')
with my_open("hello.txt") as f:
    data = f.read()
    print(data)

2.6.装饰器

python中装饰器具有强大的语法特性,允许在不修改原函数或原类的代码前提下,动态的增强功能。这不类似代理吗?与spring框架中的AOP一个道理。装饰器的核心价值点在于代码复用,和关注点分离

所以,我们常说万变不离其宗,很多东西表象(不同编程语言实现语法)不一样,但本质其实是一样的。在python中语法层面在具体一点描述装饰器,它是一个可调用对象,这里可调用对象指:函数或者类。其本质接收一个函数作为输入,返回新函数

2.6.1.装饰器应用场景

在实际应用中,装饰器所解决的问题域有:

  • 日志记录:自动记录函数调用信息
  • 执行耗时统计:统计函数执行时间
  • 权限校验:检查校验用户操作权限
  • 缓存:缓存函数结果
  • 路由注册:Flask这样的web框架,通过装饰器注册url

2.6.2.闭包

要搞清楚装饰器的运用,需要先理解闭包的概念,闭包其实就是函数嵌套。示例:

python 复制代码
# 闭包,定义函数嵌套
def my_out():
    num = 50
    # 函数内部再定义函数
    def my_in():
        return num
    #返回内部定义函数
    return my_in

# 直接调用函数
print(my_out()())

# 通过中间形式调用函数
f = my_out()
print(f())

2.6.3.简单装饰器示例

直观感受一个装饰器示例:

python 复制代码
def my_decorator(func):
    def wrapper():
        print("函数执行前")
        # 调用原函数
        func()  
        print("函数执行后")
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

say_hello()

2.6.4.带参数装饰器

装饰器本身可以有参数,像这样:

python 复制代码
# 外层接收装饰器参数
def repeat(n): 
    # 中层接收被装饰函数
    def decorator(func): 
         # 内层包装原函数
        def wrapper(*args, **kwargs): 
            for _ in range(n):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(3)
def greet(name):
    print(f"Hello, {name}!")

greet("小明")

2.6.5.保留原函数元信息

装饰器会导致原函数的 __name__ 等元信息丢失,使用 functools.wraps 解决 。像这样:

python 复制代码
from functools import wraps

def log_decorator(func):
    # 保留原函数元信息
    @wraps(func)  
    def wrapper(*args, **kwargs):
        print(f"调用函数: {func.__name__}")
        return func(*args, **kwargs)
    return wrapper

@log_decorator
def example():
    """函数文档定义"""
    pass

print(example.__name__)  
print(example.__doc__)  

2.6.6.类装饰器

除了函数实现装饰器,类同样可以作为装饰器。像这样:

python 复制代码
import time
# 定义Timer类,通过__call__实现装饰器功能
class Timer:
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        import time
        start = time.time()
        result = self.func(*args, **kwargs)
        end = time.time()
        print(f"耗时: {end - start:.2f}秒")
        return result

@Timer
def slow_function():
    time.sleep(1)

slow_function() 
相关推荐
AI赛奇19 分钟前
【清华出品】deepseek进阶版教程
人工智能·ai写作
byxdaz23 分钟前
OpenCV实现图像分割与无缝合并
人工智能·opencv·计算机视觉
九鼎创展科技35 分钟前
“全志V821:智能玩具的理想之选”——科技赋能,乐趣升级
人工智能·嵌入式硬件·ai
Firmin12345638 分钟前
使用Flask和OpenCV 实现树莓派与客户端的视频流传输与显示
python·opencv·flask
时光旅人01号1 小时前
神经网络微调技术解析
人工智能·深度学习·神经网络
rockmelodies1 小时前
基于Python的端口扫描器和目录扫描工具实现方案,结合机器学习进行指纹识别
人工智能·python·机器学习
灵动小溪1 小时前
Deepseek 本地部署
人工智能
DB_UP1 小时前
浅谈数据分析及数据思维
大数据·人工智能·数据分析
是十一月末1 小时前
Opencv之掩码实现图片抠图
人工智能·python·opencv·计算机视觉·图片识别
阿_星_1 小时前
解决pip install 出现error: subprocess-exited-with-error的问题
开发语言·python·pip