Python3进阶之函数的奥秘:探索函数的定义、调用和返回值

目录

函数的定义

def关键字

函数的作用

函数的使用方式

调用自定义函数

匿名函数

内置函数、导入模块和使用案例

经验建议1:统一返回值类型规范

经验建议2:优先使用异常替代错误编码返回

重构

总结


图片

更多关于Python的相关技术点,敬请关注公众号:CTO Plus后续的发文,有问题欢迎后台留言交流。

 

Python3是一种功能强大的编程语言,它具有许多优点,其中之一就是函数的灵活性和易用性。Python 3 中的函数是非常重要的编程概念,它们可以帮助我们组织和重用代码,实现特定的功能。

原文:Python3进阶之函数的奥秘:探索函数的定义、调用和返回值

我们知道,程序是指令的集合,我们在程序中书写的语句在执行时会变成一条或多条指令然后由CPU去执行。当然为了简化程序的设计,我们引入了函数的概念,把相对独立且经常重复使用的代码放置到函数中,在需要使用这些功能的时候只要调用函数即可,如果一个函数的功能过于复杂和臃肿,我们又可以进一步将函数继续切分为子函数来降低系统的复杂性。

函数是一种可重复使用的代码块,可以接受输入参数并返回输出结果。函数是Python3编程中的重要组成部分,它可以帮助我们将代码模块化,提高代码的可读性和可维护性。

本文我将为大家详细介绍 Python 3 中的函数,包括函数的定义、函数的作用和使用方式、参数传递和函数调用、返回值、匿名函数、内置函数和模块的使用,以及关于函数的两个经验建议,整个过程结合代码示例进行介绍,以帮助读者更好的理解函数的使用,文章最后分享了下关于“重构”这一关键词。

后面的文章将介绍作用域、递归、高阶函数的使用和开发技巧等内容,敬请关注。

函数的定义

在 Python 3 中,函数可以使用`def` 关键字进行定义,后面跟着函数名和参数列表。函数定义的一般形式如下:

def function_name(parameters):    """函数的文档字符串"""    # 函数体    # ...    return expression

其中

  1. 1.       `function_name` 是函数的名称,用于调用函数。

  2. 2.       `parameters` 是函数的参数列表,可以包括位置参数、默认参数、可变参数和关键字参数。

  3. 3.       `"""函数的文档字符串"""` 是函数的文档字符串,同时也相当于是注释,用于描述函数的作用和用法。

  4. 4.       `return expression` 是函数的返回值,可以是任意表达式。

  5. 5.       函数体:函数的具体实现逻辑。

  6. 6.       return expression:函数的返回值,可以省略,省略时函数返回 None。

接下来将依次介绍上面这6点

def关键字

在Python中可以使用def关键字来定义函数,和变量一样每个函数也需要一个能见名知意的名字,而且命名规则跟变量的命名规则是一致的。在函数名后面的圆括号中可以放置传递给函数的参数,程序中函数的参数就相当于是数学上说的函数的自变量,而函数执行完成后我们可以通过return关键字来返回一个值,这相当于数学上说的函数的因变量。

命名规则和开发规范请参考文章《通读Python PEP8代码规范》。

Python提供了几十种关键字,其他关键字可以参考文章《看这一篇就够了 Python的35个关键字的含义、作用、特性以及使用方式详解》。

函数的作用

这里介绍下函数的作用,弄清楚函数是用来做什么的,解决我们开发中的什么问题。

首先,函数在编程中起着非常重要的作用,它们可以帮助我们实现代码的模块化、重用和组织,提高代码的可读性、可维护性和可扩展性。

函数最重要的目的是方便我们重复使用相同的一段程序。将一些操作隶属于一个函数,以后你想实现相同的操作的时候,只用调用函数名就可以,而不需要重复敲所有的代码语句。

以下是我为大家总结的关于 Python 3 函数的几个主要作用:

1. 模块化

用函数封装功能模块,函数可以将一段代码封装成一个独立的模块,实现特定的功能。这样,我们可以通过函数来组织代码,使得代码更加清晰、易于理解和维护。例如,我们可以将一些相关的操作封装成一个函数,然后在需要的地方调用这个函数,从而实现代码的模块化。

2. 代码重用

函数可以帮助我们避免重复编写相同的代码,提高代码的复用性。通过定义函数,我们可以在不同的地方多次调用同一个函数,从而避免重复编写相同的代码,减少代码量,提高编程效率。

3. 提高可读性

函数可以将复杂的逻辑分解为多个简单的步骤,使得代码更易于理解。通过给函数命名,使用合适的参数名和注释,我们可以更清晰地表达代码的意图,提高代码的可读性。

4. 提高可维护性

通过将代码模块化,并使用函数来组织和封装代码,可以使得代码更易于维护。当需要修改特定功能时,只需修改对应函数的代码,而不需要影响其他部分的代码。这样可以降低修改代码时引入错误的风险,提高代码的可维护性。

5. 实现特定功能

函数可以帮助我们实现特定的功能,例如计算数学表达式、处理数据、操作文件等。通过函数,我们可以将复杂的任务分解为多个简单的步骤,然后分别实现这些步骤,从而实现特定的功能。

6. 支持递归

Python 3 函数还支持递归调用,这使得我们可以更加灵活地解决一些复杂的问题,例如计算阶乘、实现搜索算法、目录嵌套遍历、菜单嵌套遍历等情况。

更多关于Python的相关技术点,敬请关注公众号:CTO Plus后续的发文,有问题欢迎后台留言交流。

图片

函数的使用方式

函数体内的代码块需要缩进,通常使用4个空格。例如:

不带参函数

def custom_function():    """    定义一个不带参的函数    :return: None    """    print("this is Python3 function")

带参函数

def greet(name):    """    定义一个带参的函数    :param name: 名字    :return: None    """    print("Hello, my name is " + name)

在上面的例子中,我们分别定义了一个不带参数的函数custom_function,以及定义了一个带参数名为greet的函数,它接受一个参数name,并在函数体内打印出一条问候语。

带参数默认值的函数

在Python3中,函数的参数可以有默认值,这样在调用函数时可以不传入该参数,而是使用默认值。例如:

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

在上面的例子中,我们为参数greeting设置了默认值"CTO Plus",这样在调用函数时可以只传入一个参数。然后在print中使用了f-strings方法。f-strings的使用方法,请参考文末推荐阅读的文章。

带可变参的函数

Python3中的函数还支持可变参数,即可以接受任意数量的参数。使用*args表示可变参数,使用**kwargs表示关键字参数。例如:

def add(*args):    """    可变参数函数    :param args:     :return:     """    result = 0    for num in args:        result += num    return result

在上面的例子中,我们定义了一个add函数,它可以接受任意数量的参数,并将它们相加后返回结果。

除了以上介绍的基本用法之外,Python3函数还支持匿名函数、闭包、装饰器等高级特性,这些特性可以帮助我们更加灵活地使用函数。这些将在后面的章节中继续一一做介绍。

调用自定义函数

上面介绍到了函数的定义方式,但还没介绍如何使用,接下来介绍下如何调用我们自定义的函数。定义过函数后,就可以在后面程序中使用这一函数

# @author:SteveRocket # @Date:2023/11/18# @File:01function# @Email:rocket_2014@126.com# @CSDN:https://blog.csdn.net/zhouruifu2015/# @WeChat:https://mp.weixin.qq.com/s/0yqGBPbOI6QxHqK17WxU8Q
def custom_function():    """    定义一个不带参的函数    :return: None    """    print("this is Python3 function")

# 调用无参函数custom_function()

def greet(name):    """    定义一个带参的函数    :param name: 名字    :return: None    """    print("Hello, my name is " + name)  # Hello, my name is SteveRocket

greet("SteveRocket")
result = greet("SteveRocket")print(result)  # 函数返回值:None

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

greet("SteveRocket")  # Hello SteveRocket, CTO Plus

def add(*args):    """    可变参数函数    :param args:    :return:    """    result = 0    for num in args:        result += num    return result

print(add(1, 2, 3, 4, 5))  #  15print(add(11, 22, 33))  # 66

def add(x, y):    return x + y
result = add(33, 55)print(result)  # 88

输出结果

图片

                     

通过前面对函数的定义和对函数返回值的介绍,我们可以知道,使用def这个关键字定义一个函数。greet是函数名。括号中的name是函数的参数,也即是对函数的输入。函数参数可以有多个,也可以完全没有(但括号要保留),关于函数的参数详细介绍将在下一篇文章《Python3进阶之解密函数参数传递的奥秘与技巧》中做详细介绍,敬请关注。

在代码result = greet("SteveRocket") 这块属于函数的调用与参数传递,最后将返回值赋值给了result,其实此处函数的返回值是None,所以最后打印输出为None。

从上面代码片段可以看出几个特点:

  • Python的一个代码文件中可以定义多个同名的函数,比如上面的greet(name)和greet(name, greeting="CTO Plus"),以及add(*args)和add(x, y)。

  • 函数如果没有使用return语句,则函数默认有一个返回值,值为:None。


更多关于Python的相关技术点,敬请关注公众号:CTO Plus后续的发文,有问题欢迎后台留言交流。

图片

函数的返回值和return语句

接下来介绍下函数的返回值。在Python中,当程序执行到return的时候,程序将停止执行函数内余下的语句。return并不是必须的,当没有return, 或者return后面没有返回值时,函数将自动返回None。None是Python中的一个特别的数据类型,用来表示什么都没有,相当于C中的NULL。None多用于关键字参数传递的默认值。

在 Python3 中,函数可以没有返回值、返回单个值或返回多个值(以元组的形式)。此外,还可以结合使用一些高级用法来处理函数的返回值。下面将详细介绍这些情况。

1. 函数没有返回值

在 Python3 中,函数可以没有返回值,也就是说函数执行完毕后不产生任何结果。这种情况下,函数执行完最后一条语句或者执行 return 语句时,函数会自动返回 None。

示例:

def greet(name):   print("Hello, " + name)  # Hello, SteveRocket
result = greet("SteveRocket")print(result)  # None

2. 函数返回单个值

函数可以使用 return 语句返回单个值。在函数执行完毕后,可以通过 return 语句将一个值返回给调用者。

示例:

def add(x, y):   return x + y
result = add(33, 55)print(result)  # 88

3. 函数返回多个值

在 Python3 中,函数也可以返回多个值。实际上,函数返回的多个值是以元组的形式返回的。

示例:

def get_circle_info(radius):    """    计算圆的面积和周长    :param radius: 半径    :return:面积和周长    """    area = 3.14 * radius ** 2    circumference = 2 * 3.14 * radius    return area, circumference
circle_area, circle_circumference = get_circle_info(5)print(circle_area, circle_circumference)  # 78.5 31.400000000000002

关于元组的使用和特性介绍请参考文章《Python3经典数据类型元组(tuple)开发使用注意事项和代码示例详解》

匿名函数

Python 3 中支持使用`lambda` 关键字定义匿名函数。即lambda函数,也称为匿名函数,是一种简单的函数定义方式,它可以快速定义一些简单的函数,特别适用于需要编写短小的代码段的情况。

Lambda函数的语法格式如下:

lambda arguments: expression

其中,arguments是函数的参数列表,expression是函数的返回值表达式。Lambda函数可以有多个参数,也可以没有参数。

下面是一个简单的例子,使用lambda函数实现两个数相加的功能:

add = lambda x, y: x + y

print(add(2, 3)) # 输出5

在上面的例子中,我们使用lambda函数定义了一个add函数,它接受两个参数x和y,并返回它们的和。将计算的结果赋值给了变量add。

Lambda函数的特点是它们是匿名的,即没有函数名,因此可以直接将其作为参数传递给其他函数,或者将其赋值给变量。当你需要编写一次性的小函数并且不想使用关键字def来定义命名函数时,它们很有用。

Lambda函数通常用于一些简单的函数,例如对列表进行排序、筛选等操作。

除了基本的用法之外,Python3中的lambda函数还支持一些高级用法,例如:

1. 作为参数传递给其他函数

def apply(func, x):    return func(x)
result = apply(lambda x: x * x, 3)print(result)  # 输出9

在上面的例子中,我们定义了一个apply函数,它接受一个函数和一个参数x,然后将函数应用于该参数。我们使用lambda函数定义了一个平方函数,并将其作为参数传递给apply函数。

2. 与map、filter等函数结合使用

numbers = [1, 2, 3, 4, 5]

squares = list(map(lambda x: x * x, numbers))

print(squares) # 输出[1, 4, 9, 16, 25]

even_numbers = list(filter(lambda x: x % 2 == 0, numbers))

print(even_numbers) # 输出[2, 4]

在上面的例子中,我们使用lambda函数结合map函数和filter函数,分别对列表中的元素进行平方和筛选。

3. 与reduce函数结合使用

from functools import reduce

numbers = [1, 2, 3, 4, 5]

product = reduce(lambda x, y: x * y, numbers)

print(product) # 输出120

在上面的例子中,我们使用lambda函数结合reduce函数,计算列表中所有元素的乘积。

内置函数、导入模块和使用案例

以上介绍的全都是属于自定义函数,Python自身是提供了70多种内置函数的,在前面的几篇文章中我已经全部总结介绍到了,具体可以参考下面的文章:

当我们求阶乘时,我们需要计算一个数的阶乘,即将该数与比它小1的数相乘,然后再与比它小2的数相乘,以此类推,直到乘到1为止。下面是一个简单的Python3函数,可以用来求阶乘:

def factorial(n):    if n == 0 or n == 1:        return 1    else:        result = 1        for i in range(2, n + 1):            result *= i        return result

在上面的例子中,我们定义了一个名为factorial的函数,它接受一个参数n,然后使用循环计算n的阶乘,并返回结果。

你可以这样调用这个函数来计算阶乘:

print(factorial(5)) # 输出120

这将输出5的阶乘的结果,即120。

除了上面的方法之外,我们还可以使用递归来实现,关于递归的使用和介绍参数后面的文章《Python3算法实践之递归函数》。

使用内置模块简化实现

Python3的math模块中其实已经提供了一个名为factorial的函数,可以用来计算一个数的阶乘,事实上求阶乘并不用自己定义函数。它的用法非常简单,只需要将要计算阶乘的数作为参数传递给该函数即可。

下面是一个使用math模块中的factorial函数计算阶乘的例子:

import math

result = math.factorial(5)

print(result) # 输出120

在上面的例子中,我们首先导入了math模块,然后使用factorial函数计算了5的阶乘,并将结果存储在result变量中。最后,我们将结果输出到屏幕上。

需要注意的是,math模块中的factorial函数只能用于计算整数的阶乘,如果传递给该函数的参数不是整数,它会抛出ValueError异常。如果需要计算浮点数的阶乘,可以使用gamma函数。

我们这里是为了讲解函数的定义和使用才把重新实现了一遍求阶乘,实际开发中并不建议做这种低级的重复劳动(DRY原则)。

 

更多关于Python的相关技术点,敬请关注公众号:CTO Plus后续的发文,有问题欢迎后台留言交流。

图片

经验建议1:统一返回值类型规范

单个函数应该总是返回同一类数据,这点的加强介绍可以参考后面的文章《Python3进阶之函数声明中的类型注解特性(List[int]的含义)详解》。

示例1:不推荐

def is_odd(num):    if num % 2 > 0:        return True

示例2:推荐

def is_odd(num):    if num % 2 > 0:        return True    return False

示例1的代码可能会返回 bool 或者 None,这就是两种数据类型了,而示例2始终都是只返回单一的类型。

经验建议2:优先使用异常替代错误编码返回

当函数需要返回错误信息时,以抛出异常优先。

# BADdef disable_agent(ip):    if not IP_DATA.get(ip):        return {"code": ErrorCode.UnknownError, "message": "没有查询到 IP 对应主机"}

# GOODdef disable_agent(ip):    """    :raises: 当找不到对应信息时,抛出 UNABLE_TO_DISABLE_AGENT_NO_MATCH_HOST    """    if not IP_DATA.get(ip):        raise ErrorCode.UNABLE_TO_DISABLE_AGENT_NO_MATCH_HOST

重构

最后分享下关键词:重构。

我们在了解了如何定义函数后,我们可以对一些比较冗余或繁杂的功能代码块进行一定程度的重构,所谓重构就是在不影响代码执行结果(不改变软件系统外部行为)的前提下,通过调整其内部结构,以改善其可读性、可维护性、灵活性和性能等方面的过程。重构是软件开发过程中非常重要的一环,它可以帮助开发人员不断优化和改进现有的代码,使其更加健壮、高效和易于理解。

重构的主要目的包括:

1. 提高代码质量:通过重构,可以优化代码结构,减少代码重复,提高代码质量,降低代码的复杂度。

2. 提高可读性和可维护性:重构可以使代码更加清晰易懂,降低维护成本,方便后续修改和扩展。

3. 改进系统设计:通过重构可以改进系统的设计,使其更加灵活、可扩展和易于维护。

4. 优化性能:重构可以优化代码结构,提高系统性能,减少资源占用。

重构的一些常见技术包括:

1. 提取函数:将一段代码提取成一个独立的函数,提高代码的可读性和可维护性。

2. 合并函数:将功能相似的函数合并成一个函数,减少代码重复。

3. 重命名变量、函数和类:通过更加清晰的命名规范,提高代码的可读性。

4. 拆分很长的函数:将一个很长的函数拆分成多个小的函数,提高代码的可读性和可维护性。

5. 消除重复代码:通过抽取重复代码,减少代码冗余。

总结

总之,要写出高质量的代码首先要解决的就是重复代码的问题。Python 3 函数在编程中具有非常重要的作用,它们可以帮助我们组织和重用代码,实现特定的功能,提高代码的可读性、可维护性和可扩展性。因此,熟练掌握函数的使用是成为一名优秀的 Python 开发者的重要一步。

更多关于Python的相关技术点,敬请关注公众号:CTO Plus后续的发文,有问题欢迎后台留言交流。

图片

Python专栏
https://blog.csdn.net/zhouruifu2015/category_5742543

欢迎关注公众号CTO Plus,有问题欢迎后台留言交流。

更多精彩,关注我公号,一起学习、成长

 

Python设计模式:

推荐阅读:

最后,不少粉丝后台留言问加技术交流群,之前也一直没弄,所以为满足粉丝需求,现建立了一个关于Python相关的技术交流群,加群验证方式必须为本公众号的粉丝,群号如下:

图片

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要实现 Python 调用 C++ 函数并返回 cv::Mat,可以使用以下步骤: 1. 在 C++ 中编写一个函数,该函数接受输入参数并返回 cv::Mat 类型的值。例如: ```c++ #include <opencv2/opencv.hpp> cv::Mat myFunction(cv::Mat inputImage) { // 这里可以进行一些图像处理操作 cv::Mat outputImage = inputImage.clone(); // 这里只是简单地将输入图像复制到输出图像中 return outputImage; } ``` 2. 将 C++ 函数编译为动态链接库(DLL)或共享对象(SO)文件,以便能够从 Python调用函数。 3. 在 Python 中使用 ctypes 模块加载 C++ 动态链接库或共享对象,并使用 ctypes 将输入参数传递给 C++ 函数,并将返回值转换为 Python 中的 numpy 数组或 PIL 图像等格式。例如: ```python import numpy as np import ctypes import cv2 # 加载 C++ 动态链接库或共享对象 my_lib = ctypes.cdll.LoadLibrary('./my_lib.so') # 定义 C++ 函数的输入和输出类型 my_lib.myFunction.argtypes = [ctypes.c_void_p] my_lib.myFunction.restype = ctypes.c_void_p # 加载输入图像并将其转换为 cv::Mat 类型 input_image = cv2.imread('input.jpg') input_mat = cv2.cvtColor(input_image, cv2.COLOR_BGR2RGB) input_mat_ptr = ctypes.c_void_p(input_mat.ctypes.data) # 调用 C++ 函数并将返回值转换为 numpy 数组 output_mat_ptr = my_lib.myFunction(input_mat_ptr) output_mat = np.ctypeslib.as_array(output_mat_ptr, shape=input_mat.shape) # 将 cv::Mat 转换为 PIL 图像 output_image = cv2.cvtColor(output_mat, cv2.COLOR_RGB2BGR) pil_image = Image.fromarray(output_image) pil_image.show() ``` 以上就是实现 Python 调用 C++ 函数并返回 cv::Mat 的一般方法。注意,在使用 ctypes 模块进行转换时,需要确保传递给 C++ 函数的指针和返回的指针类型正确,并且需要进行适当的内存管理以避免内存泄漏。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SteveRocket

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值