Python函数和代码复用

简介: 函数是一段具有特定功能的,可重用的语句组,通过函数名来表示和调用。经过定义,一组语句等于一个函数,在需要使用这组语句的地方,直接调用函数名称即可。因此,函数包括两部分:函数的定义和函数的调用。

Python函数和代码复用

什么是函数:

  函数是一段具有特定功能的,可重用的语句组,通过函数名来表示和调用。经过定义,一组语句等于一个函数,在需要使用这组语句的地方,直接调用函数名称即可。因此,函数包括两部分: 函数的定义函数的调用

为什么要使用函数:

  • 代码复用
  • 影藏实现细节
  • 提高可维护性
  • 提高可读性便于调试
  • 降低编程难度

一、函数的定义

语法格式:

def  函数名 ([参数列表]):
    函数体
    return 返回值列表 

例:

# -*- coding: utf-8 -*-
# @File  : demo.py
# @author: Flyme awei 
# @email : Flymeawei@163.com
# @Time  : 2022/8/14 17:02

def calc(a, b):  # 函数定义
    c = a + b
    return c

二、函数的调用

函数的定义也叫函数“声明”,定义后的函数不能直接运行,需要经过“调用”才能得到运行。

语法格式:

函数名(实际赋值参数列表)
# 函数创建
def calc(a, b):  # 函数定义
    c = a + b
    return c

'''
函数调用:
函数名(实际参数列表)'''
d = calc(10, 20)  # 函数调用
print(d)  # 30

三、函数的参数传递

函数的参数在定义时可以指定默认值,当函数被调用时,如果没人传入对应的参数时,则使用函数定义时的默认值替代。

语法格式

def  函数名(非可选参数列表,可选参数列表=默认值):
    函数体
    return 返回值列表 

1.形式参数与实际参数

  • 函数定义处的参数称为形式参数
  • 函数调用处的参数称为实际参数

2.位置传参与关键字传参

# -*- coding: utf-8 -*-
# @File  : demo.py
# @author: Flyme awei 
# @email : Flymeawei@163.com
# @Time  : 2022/8/14 17:02

# 函数的参数传递
'''
1.位置传参 根据形参对应的位置进行参数传递
2.关键字实参 根据形参名称进行参数传递
'''

def calc(a, b):  # a b 为函数定义当处的形式参数
    c = a + b
    return c


calc(10, 20)  # 10 20 为函数调用处的实际参数

# 位置实参
print(calc(10, 20))  

# =左侧的变量的名称称为关键字参数
print(calc(b=10, a=20))  

在这里插入图片描述

3.可变对象与不可变对象的参数传递

在函数调用过程中,进行参的传递:

  • 如果是不可变对象,函数体的修改不会影响实参的值
  • 若果是可变对象,函数体的改变会影响到实参的值
# -*- coding: utf-8 -*-
# @File  : demo.py
# @author: Flyme awei 
# @email : Flymeawei@163.com
# @Time  : 2022/8/14 17:02

'''
在函数调用过程中,进行参的传递:
如果是不可变对象,函数体的修改不会影响实参的值
若果是可变对象,函数体的改变会影响到实参的值
'''


def fun(arg1, arg2):
    print('arg1=', arg1)
    print('arg2=', arg2)
    arg1 = 100  # arg1 的修改为100不会影响n1的值
    arg2.append(200)  # are2 的修改会影响到n2的值
    print('arg1=', arg1)  # 100
    print('arg2=', arg2)  # [10, 20, 200]
    return arg1, arg2


a = 10
b = [10, 20]
print('a', a)  # 10
print('b', b)  # [10, 20]
x = fun(a, b)  # 位置传参 arg1,arg2时是函数定义处的形参,n1,n2是函数调用处的实参, 实参和形参的名称可以不一致
print(a)  # 10
print(b)  # [10, 20, 200]
print(x)  # (100, [10, 20, 200])

在这里插入图片描述

4.个数可变的位置、关键字参数

  • 个数可变的位置参数: *arges
参数定义时,可能无法事先确定传递的位置实参的个数,使用可变的位置参数
  • 个数可变的关键字形参:**kwargs
参数定义时,可能无法事先确定传递的位置实参的个数,使用可变的位置参数

在一个函数的定义过程中,既有个数可变的 *arges位置形参,又有个数可变的**kwargs关键字形参,要求把位置形参放在前面

# -*- coding: utf-8 -*-
# @File  : demo.py
# @author: Flyme awei 
# @email : Flymeawei@163.com
# @Time  : 2022/8/14 17:02


# 个数可变的位置参数 *arges
# 参数定义时,可能无法事先确定传递的位置时参的个数,使用可变的位置参数

def fun(*args):  # 函数定义时,可变的位置参数
    print(args)  # 返回值为元组
    # print(args[0])  返回元组的第1个对象


fun(10)  # (10, )
fun(10, 20)  # (10, 20)
fun(11, 22, 33)  # (11, 22, 33)


# 个数可变的关键字形参
# 参数定义时,可能无法事先确定传递的位置是参的个数,使用可变的位置参数
def fun(**kwargs):
    print(kwargs)  # 返回值是 字典


fun(a=10)  # {'a': 10}
fun(a=10, b=20, c=30)  # {'a': 10, 'b': 20, 'c': 30}

'''
def fun2(*args,*a)
    pass
以上程序报错,个数可变的的位置参数值能有一个
def fun2(**kwargs)
    pass
个数可变的关键字参数也只能有一个
'''

# 在一个函数的定义过程中,既有个数可变的位置形参,又有个数可变的关键字形参,要求把位置形参放在前面
def fun(*args, **kwargs):
    pass
    

在这里插入图片描述

5.函数参数总结(一)

# -*- coding: utf-8 -*-
# @File  : demo.py
# @author: Flyme awei 
# @email : Flymeawei@163.com
# @Time  : 2022/8/14 17:02


def fun(a, b, c):  # a,b,c在函数定义处,所以是形式参数
    print('a=', a)
    print('b=', b)
    print('c=', c)


# 函数调用
fun(10, 20, 30)  # 函数调用时的参数传递,称为位置传参
lst = [11, 22, 33]
fun(*lst)  # 函数调用,将列表中的每个元素都转换为位置实参传递

fun(a=100, b=200, c=300)  # 函数调用,所以是关键字实参
dic = {'a': 111, 'b': 222, 'c': 333}
print(fun(**dic))  # 函数调用时,将字典中的键值对都转换为关键字实参传递

在这里插入图片描述

6.函数参数总结(二)

def fun(a, b=10):  # a是形式参数

    print('b=', b)


def fun2(*args):  # 个数可变的位置形参
    print(args)


def fun3(**kwargs):  # 个数可变的关键字形参
    print(kwargs)


# 函数调用
fun(10)
fun(10, 20)
fun2(10, 20, 30)
fun3(a=10, b=20)
print('--------------------------')


def fun4(a, b, *, c, d):  # 需求 c,d 只能采用关键字实参传递
    print('a=', a)
    print('b=', b)
    print('c=', c)
    print('d=', d)


# fun4(10, 20, 30, 40)   # 位置实参传递
fun4(a=10, b=20, c=30, d=40)  # 关键字实参传递
print('--------------------------')
fun4(10, 20, c=30, d=40)  # 前面两个进行位置实参传递,后面两个采用关键字实参传递

''' 函数定义时的形参顺序问题'''


def fun5(a, b, *, c, d, **kwargs):
    pass


def fun6(*args, **kwargs):
    pass


def fun7(a, b=10, *args, **kwargs):
    pass

在这里插入图片描述

四、函数的返回值

   return语句用来结束函数并将程序返回到函数调用的位置继续执行。 return语句可以出现在函数中的任何部分,同时可以将 0个、 1个或多个函数运算的结果返回给函数被调用处的变量。

函数的返回值

  1. 如果没有返回值(函数执行完毕后,不需要给调用处提供数据),return可以省略不写
  2. 若果返回值为1个,直接返回类型原类型
  3. 如果返回值为个,返回结果为元组
# -*- coding: utf-8 -*-
# @File  : demo.py
# @author: Flyme awei 
# @email : Flymeawei@163.com
# @Time  : 2022/8/14 17:02

'''
函数的返回值:
(1)如果没有返回值(函数执行完毕后,不需要给调用处提供数据),return可以省略不写
(2)若果返回值为1个,直接返回类型原类型
(2)如果返回值为多个,返回结果为元组
'''


def fun(lst):
    odd = []
    even = []
    for i in lst:
        if i % 2:
            odd.append(i)
        else:
            even.append(i)
    print(odd, even)
    return odd, even  # 没有返回值,可以省略  如果返回值为多个,返回结果为元组


lst1 = [12, 34, 45, 57, 67, 78, 89]
print(lst1)

# 函数调用
print(type(fun(lst1)))
'''函数定义时,是否需要返回值,视情况而定'''

在这里插入图片描述

五、变量的作用域

变量的作用域:程序代码能访问该变量的区域
  1. 局部变量:在函数内定义并使用的变量,只在函数内部有效,局部变量使用global声明,这个变量就会变成全局变量
  2. 全局变量:函数体外定义的变量,可作用于函数内外
# -*- coding: utf-8 -*-
# @File  : demo.py
# @author: Flyme awei 
# @email : Flymeawei@163.com
# @Time  : 2022/8/14 17:02

# 变量的作用域:程序代码能访问该变量的区域
'''
1.局部变量 在函数内定义并使用的变量,只在函数内部有效,局部变量使用global声明,这个变量就会变成全局变量
2.全局变量 函数体外定义的变量,可作用于函数内外
'''


def fun(a, b):
    c = a+b  # c,在函数内定义的变称为局部变量  a,b为函数的形参,作用范围也在在函数内部,相当于局部变量
    print(c)


name = '阿伟'  # 函数外部定义的变量,全局变量,函数体内外都可以使用
print(name)  # 阿伟


def fun2(self):
    print(name)
# 函数调用


fun2(name)  # 阿伟


def fun3():  # 函数定义
    global age  # 函数内部定义的变量,局部变量  使用global声明,变量就变为全局变量
    print(age)  # 20


age = 20
fun3()  # 函数调用
print(age)  # 20

在这里插入图片描述

六、代码复用

  函数是程序的一种基本抽象方式,它将一系列代码组织起来通过命名供其他程序使用。函数封装的直接好处是代码复用,任何其他代码只要输入参数即可调用函数,从而避免相同功能的代码在被调用处重复编写。代码复用有另一个好处,当更新函数功能时,所有被调用处的功能都被更新。

  程序由一系列代码组成,如果代码是顺序但无组织的,不仅不利于阅读和理解,也很难进行升级和维护。当程序长度在百行以上,如果不划分模块,程序的可读性就已经很糟糕了。解决这一问题最好的方法是将一个程序分割成短小的程序段,每一段程序完成一个小的功能。使用函数对合理划分为功能模块,并基于模块设计程序是一种常用方法,被称为“模块化设计”。

  模块化设计是指函数的封装功能将程序划分成主程序、子程序和子程序间关系的表达。模块化设计是使用函数设计的思考方法, 以功能块为基本单位,一般有两个基本要求:

  • 紧耦合:尽可能合理划分功能块,功能块内部耦合紧密;
  • 松耦合:模块间关系尽可能简单,功能块之间耦合度低。

   使用函数只是模块化设计的必要非充分条件,根据计算需求合理划分函数十分重要。一般来说,完成特定功能或被经常复用的一组语句应该采用函数来封装,并尽可能减少函数间参数和返回值的数量。

七、递归函数

1.什么是递归函数

如果在一个函数的函数体内调用了该函数本身,这个函数就称为递归函数。

2.递归的组成部分

递归调用递归终止条件

3.递归的调用过程

每递归调用一次函数,都会在栈内存分配一个栈帧,每执行完一次函数,都会释放相应的空间。

4.递归的优缺点

缺点: 占用内存多,效率低下
优点: 思路和代码简单
  • 使用递归函数计算阶乘
# 1.使用递归函数计算阶乘
def fun(n):  # 阶乘函数
    if n == 1:
        return 1
    elif n == 2:
        return 2
    else:
        return n * fun(n-1)


print(fun(6))  # 720
  • 斐波那契数列
# 2.斐波那契数列 1 1 2 3 5 8 13 ...
def fib(n):  # 斐波那契函数
    if n == 1:
        return 1
    elif n == 2:
        return 1
    else:
        return fib(n - 1) + fib(n - 2)  # 求斐波那契数列的第 n 项


print(fib(6), end=' ')  # 8
相关文章
|
12天前
|
缓存 监控 测试技术
Python中的装饰器:功能扩展与代码复用的利器###
本文深入探讨了Python中装饰器的概念、实现机制及其在实际开发中的应用价值。通过生动的实例和详尽的解释,文章展示了装饰器如何增强函数功能、提升代码可读性和维护性,并鼓励读者在项目中灵活运用这一强大的语言特性。 ###
|
12天前
|
存储 缓存 监控
Python中的装饰器模式:提升代码复用性与可读性的利器
本文深入探讨了Python中装饰器模式的工作原理、应用场景及其在提高代码复用性和可读性方面的优势。不同于传统的函数调用和类继承,装饰器提供了一种优雅的方式来扩展或修改函数和类的行为。通过实际案例分析,本文揭示了如何有效地利用装饰器来优化代码结构,减少冗余,以及增强程序的模块化设计。此外,文章还讨论了装饰器与生成器、上下文管理器等其他Python特性的结合使用,展示了其在复杂编程任务中的应用潜力。
|
12天前
|
存储 缓存 监控
掌握Python装饰器:提升代码复用性与可读性的利器
在本文中,我们将深入探讨Python装饰器的概念、工作原理以及如何有效地应用它们来增强代码的可读性和复用性。不同于传统的函数调用,装饰器提供了一种优雅的方式来修改或扩展函数的行为,而无需直接修改原始函数代码。通过实际示例和应用场景分析,本文旨在帮助读者理解装饰器的实用性,并鼓励在日常编程实践中灵活运用这一强大特性。
|
1月前
|
Python
Python之函数详解
【10月更文挑战第12天】
Python之函数详解
|
1月前
|
存储 数据安全/隐私保护 索引
Python 散列类型三以及函数基础
【10月更文挑战第11天】
Python 散列类型三以及函数基础
|
20天前
|
设计模式 缓存 测试技术
Python中的装饰器:功能增强与代码复用的艺术####
本文将深入探讨Python中装饰器的概念、用途及实现方式,通过实例演示其如何为函数或方法添加新功能而不影响原有代码结构,从而提升代码的可读性和可维护性。我们将从基础定义出发,逐步深入到高级应用,揭示装饰器在提高代码复用性方面的强大能力。 ####
|
26天前
|
测试技术 数据安全/隐私保护 Python
探索Python中的装饰器:简化和增强你的函数
【10月更文挑战第24天】在Python编程的海洋中,装饰器是那把可以令你的代码更简洁、更强大的魔法棒。它们不仅能够扩展函数的功能,还能保持代码的整洁性。本文将带你深入了解装饰器的概念、实现方式以及如何通过它们来提升你的代码质量。让我们一起揭开装饰器的神秘面纱,学习如何用它们来打造更加优雅和高效的代码。
|
28天前
|
弹性计算 安全 数据处理
Python高手秘籍:列表推导式与Lambda函数的高效应用
列表推导式和Lambda函数是Python中强大的工具。列表推导式允许在一行代码中生成新列表,而Lambda函数则是用于简单操作的匿名函数。通过示例展示了如何使用这些工具进行数据处理和功能实现,包括生成偶数平方、展平二维列表、按长度排序单词等。这些工具在Python编程中具有高度的灵活性和实用性。
|
1月前
|
Python
python的时间操作time-函数介绍
【10月更文挑战第19天】 python模块time的函数使用介绍和使用。
31 4
|
1月前
|
存储 Python
[oeasy]python038_ range函数_大小写字母的起止范围_start_stop
本文介绍了Python中`range`函数的使用方法及其在生成大小写字母序号范围时的应用。通过示例展示了如何利用`range`和`for`循环输出指定范围内的数字,重点讲解了小写和大写字母对应的ASCII码值范围,并解释了`range`函数的参数(start, stop)以及为何不包括stop值的原因。最后,文章留下了关于为何`range`不包含stop值的问题,留待下一次讨论。
22 1
下一篇
无影云桌面