【Python编程】八、Python函数详解

简介: 【Python编程】八、Python函数详解

一、函数的概念

什么是函数?

  • 函数与过程的区别:过程没有返回值,函数有返回值。(过程就是没有返回值的函数,过程返回None) - 过程也是函数
    python中函数可以嵌套定义,但是调用外层函数时不会执行内部定义的函数,函数只有在调用的时候才会去执行,要区分调用和定义。

函数返回值

  • 如果函数返回值的数量为0 — 返回None
  • 如果函数返回值的数量为1 — 返回object
  • 如果函数返回值数量大于1 — 返回tuple

二、变量作用域

变量作用域指的是变量生效的范围,主要分为两类:局部变量全局变量

  • 局部变量

局部变量是定义在函数体内部的变量,只在函数体内部生效。

def testA():
    a = 100
    print(a)
testA()  # 100
print(a)  # 报错:name 'a' is not defined

变量a是定义在testA函数内部的变量,在函数外部访问则立即报错。

局部变量的作用:在函数体内部,临时保存数据,即当函数调用完成后,则销毁局部变量。——栈变量,自动析构。

  • 全局变量

全局变量是在函数体内、外都能生效的变量。

# 定义全局变量a
a = 100
def testA():
    print(a)  # 访问全局变量a,并打印变量a存储的数据
def testB():
    print(a)  # 访问全局变量a,并打印变量a存储的数据
testA()  # 100
testB()  # 100

如果在函数内修改全局变量的值,应该怎么做呢,请看下面的例子:

a = 100
def testA():
    print(a)
def testB():
  '''
  # global 关键字声明a是全局变量
    global a
    a = 200 #这样表示在函数内修改全局变量
    '''
    a = 200  #定义了一个局部变量,不会修改全局变量的值
    print(a)
testA()  # 100
testB()  # 200
print(f'全局变量a = {a}')  # 全局变量a = 100

在函数内操作的都是局部变量,生命周期只在函数内,不会影响全局变量,如果局部变量与全局变量同名,相当于重新创建了一个变量,它和全局变量没有任何关系。要想在函数内操作全局变量,需要加global关键字,加了global声明后,在函数体内部操作的与全局变量同名的变量都是指全局变量。

不加global声明的时候,对于可变对象,虽然在函数体内无法对全局变量重新赋值但是可以通过内部方法改变。

  • global — 全局作用域中的变量
  • nonlocal — 上一级作用域中的变量
g_var = 10
def change_var():
  g_var = 11 
    global g_var 
  print(g_var)

这样会报错,因为这样的话,函数体内会有两个重名的变量,一个是全局变量,一个是局部变量,它们俩都叫g_var。

三、函数的参数

型参与实参的区别:

  • 形参变量只有在被调用时才会分配内存,在调用结束后,立即释放分配的内存。因此,形参只在函数内部有效。函数调用结束,返回主调函数之后,就不能再使用形参变量了。
  • 实参可以是常量、变量、表达式、函数等等,无论实参是什么类型,在函数调用的时候,都必须指定确定的值,因为要把这个值传递给形参。

函数参数主要有以下几种

(1)位置参数

位置参数:调用函数时根据函数定义的参数位置来传递参数。

def user_info(name, age, gender):
    print(f'您的名字是{name}, 年龄是{age}, 性别是{gender}')
user_info('Su', 20, '女')

使用位置参数传参的时候,传递和定义参数的顺序及个数必须一致。——实参与形参位置一一对应。

(2)关键字参数

函数调用,通过键值对的形式加以指定。可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求。

def user_info(name, age, gender):
    print(f'您的名字是{name}, 年龄是{age}, 性别是{gender}')
user_info('Su', age=20, gender='女')
user_info('alex', gender='男', age=16)

注意:函数调用时,如果有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序。

(3)缺省参数

缺省参数也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用)。

def user_info(name, age, gender='男'):
    print(f'您的名字是{name}, 年龄是{age}, 性别是{gender}')
user_info('TOM', 20)
user_info('Rose', 18, '女')

函数调用时,如果为缺省参数传值则修改默认参数值;否则使用默认值。

(4)不定长参数

不定长参数也叫可变参数。用于不确定调用的时候会传递多少个参数(不传参也可以)的场景。此时,可用包裹(packing)位置参数,或者包裹关键字参数,来进行参数传递。

  • *args – 位置参数,列表
  • **kwargs – 关键字参数,字典,键值对
  • def func(arg, *args, **kwargs) — 可接收一切参数

包裹位置传递

def user_info(*args):
    print(args)
# ('TOM',)
user_info('TOM')
# ('TOM', 18)
user_info('TOM', 18)

注意:传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是包裹位置传递。

包裹关键字传递

def user_info(**kwargs):
    print(kwargs)
# {'name': 'TOM', 'age': 18, 'id': 110}
user_info(name='TOM', age=18, id=110)

综上:无论是包裹位置传递还是包裹关键字传递,都是一个组包的过程。

(5)引用

在python中,值是靠引用来传递来的。

我们可以用id()来判断两个变量是否为同一个值的引用。我们可以将id值理解为那块内存的地址标识。

# 1. int类型
a = 1
b = a
print(b)  # 1
print(id(a))  # 140708464157520
print(id(b))  # 140708464157520
a = 2
print(b)  # 1,说明int类型为不可变类型 
print(id(a))  # 140708464157552,此时得到是的数据2的内存地址
print(id(b))  # 140708464157520
# 2. 列表
aa = [10, 20]
bb = aa
print(id(aa))  # 2325297783432
print(id(bb))  # 2325297783432
aa.append(30)
print(bb)  # [10, 20, 30], 列表为可变类型
print(id(aa))  # 2325297783432
print(id(bb))  # 2325297783432

四、递归

递归是指函数内部自己调用自己,递归具有以下特性:

  • 必须有一个明确的结束条件,否则就会无限递归;
  • 每一次进入更深一层的递归时,问题的规模相比上次递归都应有所减小;
  • 递归的效率较低,递归层次过多会导致栈溢出。在计算机中,函数调用是通过栈这种数据结构实现的,每当进入一个函数调用,栈就会增加一层栈帧,每当函数返回,栈就会减少一层栈帧,因为栈是有大小的,所以多层递归可能导致栈溢出。

五、匿名函数——lambda表达式

使用lambda关键字定义,匿名函数没有函数名 – 赋值给变量,通过变量调用匿名函数。

语法格式:lambda 形参:返回值

  • lambda表达式的参数可有可无,函数的参数在lambda表达式中完全适用。
  • lambda表达式能接收任何数量的参数但只能返回一个表达式的值。
lambda m_str:m_str+’…’
func = lambda m_str:m_str+’…’
func(‘hello’)
#相当于
def func(m_str):
    return m_str+’…’

六、函数式编程

把函数作为参数传入,这样的函数称为高阶函数,高阶函数是函数式编程的体现。函数式编程就是指这种高度抽象的编程范式。

编程方法论有三种:面向过程、函数式编程、面向对象。

函数式编程: 函数式=编程语言定义的函数+数学意义的函数;函数式就是用编程语言去实现数学函数,这种函数内对象是永恒不变的,没有for循环和while循环,所有循环都由递归实现,也不需要变量去保存状态。

  • 没有变量的定义和赋值操作即不需要变量去保存状态;
  • 函数即变量,函数可以作为参数、返回值;
#函数做参数
def func1():
  return ‘hello’
def func2(arg)
  print(‘arg is - %s’ %arg)
func2(func1)
func2(func1())
#函数做返回值
def func1():
  pass
def func2():
  return func1
def func3():
    return func1()

在python中,函数名加()就表示运行该函数。如果一个函数接收的参数或者返回值是函数名(是函数名,不是加括号的),那么这个函数就是高阶函数。一定要写函数名,不要加(),因为一加()就运行了。

尾调用

尾调用就是指在函数的最后一步(不是最后一行,是最后一步)调用另一个函数。

尾递归调用优化:在函数的最后一步去递归。

Python内置高阶函数

  • map函数 - map(逻辑方法, 可迭代对象) - for循环遍历可迭代对象,并通过逻辑方法处理每一个元素。一般逻辑方法是加减乘除等操作。
    print(‘内置函数map’, list(map(lambda x:x+1, [1, 2, 3, 4])))
  • reduce函数
    python2可直接使用,python3使用reduce需要导入
    from functools import reduce
    reduce(function, sequence, initial=None)
    把列表sequence中的数据通过function压缩在一起成为一个数,可以指定基数initial。
  • filter函数 - filter(逻辑方法, 可迭代对象) - 逻辑方法会得到一个bool值,将列表中为True的元素保留,也就是过滤出可迭代对象中符合条件的元素。一般逻辑方法是判断是否符合条件的一个判断表达式,表达式结果是bool。
  • map和filter得到的都是一个可迭代对象-迭代器。都是对列表遍历进行操作,map不改变列表顺序和元素个数。reduce是将列表进行合并操作。

Python内置函数

  • bytes(‘你好’, encoding=’utf-8’, decode(‘utf-8’)) 对’你好’进行编解码,如果不写,python默认使用utf-8编解码。(ascii/gbk/utf-8)
  • chr() 获取ascii码 – ord()
  • dir() 获取对象的属性和方法的名字
  • divmod(10, 3) 获取10除以3的商和余数
  • eval() 将字符串中的数据结构提取出来;得到字符串中的数学运算结果。
  • hash() 得到一个哈希值 - 哈希值的长度固定,通过哈希值不能推出原来的变量值,在同一个程序中同一值的哈希值是不变的。(用途:软件在官网上本身就带一个哈希值,当下载软件后会把哈希值一块下载,下载后会计算一个哈希值,如果两个哈希值相同说明软件在中途没有被篡改,是安全的)
  • 可哈希数据类型 - 不可变数据类型
  • 不可哈希数据类型 – 可变数据类型
  • globals() 打印全局变量
  • locals() 打印局部变量
  • zip() 把两个序列变成一一对应的关系,返回的结果是可迭代的
  • max() 高级用法 – 只要是for可迭代,就能通过max取最大值
    people = {“su”:17, “liu”:18, “fan”:19}
    print(list(max(zip(people.values(), people.keys()))))
    #对于键值对,默认是比较key,如果想比较value并打印出键值对
    #可以通过zip把键值对翻过来,然后再比较
  • list()相当于迭代,可以迭代列表中所有元素,print(list())可以迭代打印
  • max()比较的时候是按照位置一个一个往后比较的,所以字典之间无法比较,因为字典是无序的。

  • slice() 切片 l[start, end] → s=slice(start, ent) l[s]
  • import() 通过字符串的方式导入模块
import 导入模块
import test   #test就是一个py文件
test.func()    #通过.来使用test.py提供的功能
m = __import__(‘test’)
m.func()


目录
打赏
0
0
0
0
13
分享
相关文章
探索Python编程:从基础到高级
在这篇文章中,我们将一起深入探索Python编程的世界。无论你是初学者还是有经验的程序员,都可以从中获得新的知识和技能。我们将从Python的基础语法开始,然后逐步过渡到更复杂的主题,如面向对象编程、异常处理和模块使用。最后,我们将通过一些实际的代码示例,来展示如何应用这些知识解决实际问题。让我们一起开启Python编程的旅程吧!
Python编程入门:从零基础到实战应用
本文是一篇面向初学者的Python编程教程,旨在帮助读者从零开始学习Python编程语言。文章首先介绍了Python的基本概念和特点,然后通过一个简单的例子展示了如何编写Python代码。接下来,文章详细介绍了Python的数据类型、变量、运算符、控制结构、函数等基本语法知识。最后,文章通过一个实战项目——制作一个简单的计算器程序,帮助读者巩固所学知识并提高编程技能。
Python入门:8.Python中的函数
### 引言 在编写程序时,函数是一种强大的工具。它们可以将代码逻辑模块化,减少重复代码的编写,并提高程序的可读性和可维护性。无论是初学者还是资深开发者,深入理解函数的使用和设计都是编写高质量代码的基础。本文将从基础概念开始,逐步讲解 Python 中的函数及其高级特性。
Python入门:8.Python中的函数
[oeasy]python053_学编程为什么从hello_world_开始
视频介绍了“Hello World”程序的由来及其在编程中的重要性。从贝尔实验室诞生的Unix系统和C语言说起,讲述了“Hello World”作为经典示例的起源和流传过程。文章还探讨了C语言对其他编程语言的影响,以及它在系统编程中的地位。最后总结了“Hello World”、print、小括号和双引号等编程概念的来源。
126 80
|
26天前
|
Python高性能编程:五种核心优化技术的原理与Python代码
Python在高性能应用场景中常因执行速度不及C、C++等编译型语言而受质疑,但通过合理利用标准库的优化特性,如`__slots__`机制、列表推导式、`@lru_cache`装饰器和生成器等,可以显著提升代码效率。本文详细介绍了这些实用的性能优化技术,帮助开发者在不牺牲代码质量的前提下提高程序性能。实验数据表明,这些优化方法能在内存使用和计算效率方面带来显著改进,适用于大规模数据处理、递归计算等场景。
63 5
Python高性能编程:五种核心优化技术的原理与Python代码
|
2月前
|
[oeasy]python055_python编程_容易出现的问题_函数名的重新赋值_print_int
本文介绍了Python编程中容易出现的问题,特别是函数名、类名和模块名的重新赋值。通过具体示例展示了将内建函数(如`print`、`int`、`max`)或模块名(如`os`)重新赋值为其他类型后,会导致原有功能失效。例如,将`print`赋值为整数后,无法再用其输出内容;将`int`赋值为整数后,无法再进行类型转换。重新赋值后,这些名称失去了原有的功能,可能导致程序错误。总结指出,已有的函数名、类名和模块名不适合覆盖赋新值,否则会失去原有功能。如果需要使用类似的变量名,建议采用其他命名方式以避免冲突。
53 14
|
1月前
|
[oeasy]python057_如何删除print函数_dunder_builtins_系统内建模块
本文介绍了如何删除Python中的`print`函数,并探讨了系统内建模块`__builtins__`的作用。主要内容包括: 1. **回忆上次内容**:上次提到使用下划线避免命名冲突。 2. **双下划线变量**:解释了双下划线(如`__name__`、`__doc__`、`__builtins__`)是系统定义的标识符,具有特殊含义。
32 3
|
1月前
|
深入理解 Python 的 eval() 函数与空全局字典 {}
`eval()` 函数在 Python 中能将字符串解析为代码并执行,但伴随安全风险,尤其在处理不受信任的输入时。传递空全局字典 {} 可限制其访问内置对象,但仍存隐患。建议通过限制函数和变量、使用沙箱环境、避免复杂表达式、验证输入等提高安全性。更推荐使用 `ast.literal_eval()`、自定义解析器或 JSON 解析等替代方案,以确保代码安全性和可靠性。
48 2
[oeasy]python061_如何接收输入_input函数_字符串_str_容器_ 输入输出
本文介绍了Python中如何使用`input()`函数接收用户输入。`input()`函数可以从标准输入流获取字符串,并将其赋值给变量。通过键盘输入的值可以实时赋予变量,实现动态输入。为了更好地理解其用法,文中通过实例演示了如何接收用户输入并存储在变量中,还介绍了`input()`函数的参数`prompt`,用于提供输入提示信息。最后总结了`input()`函数的核心功能及其应用场景。更多内容可参考蓝桥、GitHub和Gitee上的相关教程。
18 0
|
2月前
|
Python中的函数是**一种命名的代码块,用于执行特定任务或计算
Python中的函数是**一种命名的代码块,用于执行特定任务或计算
66 18

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等