Python入门(函数)

一.基础认识

一种映射关系

1.1什么是函数呢?

  • 概念

    函数是可以重复执行的语句块,可以重复调用

  • 作用

    用于封装语句块,提高代码的重用性

1.2函数的定义

语法:

def function():    #def为关键字,function为函数名

        #语句 想要执行的操作

        return re   #re为返回值

二.函数的调用

函数名后+小括号()表示函数的执行

2.1基本用法

语法:  函数名(实际调用的参数)

2.2调用传参

2.2.1位置传参

最为常见,参数按定义的位置传入函数

def fun1(name,age):
    print(f"l am {name},l am {age} years old") #此时语法为f-string f后紧跟字符串python会对{}中的表达式求值然后输出
fun1("hhh",18)   #l am hhh,l am 18 years old
2.2.2关键字传参

通过关键词参数的名称来传值,无顺序限制

​
def fun2(name,age):
    print(f"hello{name},l am{age}")
fun2(name="hhh",age=18)  #hellohhh,l am18

​
2.2.3参数默认值

定义函数时可以为参数指定默认值,不传参就是默认值

注意:默认值参数必须位于无默认参数后面

def fun3(name,age=18):
    print(f"hello {name},l am {age}) 
fun3("hhh")   #hello hhh,l am 18
2.2.4可变位置参数

使用*arg课接受任意数量的位置参数,*arg会将多余的位置参数收集成一个元组

#可变位置参数
def fun(a,*arg):
    print(a)
    print(arg)
fun("a1",5,8,6,9,6,)    #a1  (5, 8, 6, 9, 6)
2.2.5可变关键词参数

使用**kwargs可以让函数接受任意数量的关键词参数,多余收集成一个字典

def fun(a,**arg):
    print(a)
    print(arg)

fun(18,b=1,c=2)
2.2.6多参数解包

python中允许在调用时解包序列或字典使其作为位置参数或关键词参数传递给函数

2.2.6.1解包位置参数
#解包位置参数
def fun(name,age):
    print(f"hello{name},l am {18}")

a=(666,18)    
fun(*a)    #hello666,l am 18
2.2.6.2解包关键词参数
#解包关键词参数  即字典
def fun(name,age):
    print(f"hello{name},l am {18}")

a={"name":"hhh","age":18}    
fun(**a)  #hellohhh,l am 18
2.2.7参数混合使用

注意:位置参数必须放在关键词参数前面  (有默认参数位于无默认参数后)

三.可变和不可变参数

python中,实参可以是可变类型和不可变类型。他们的区别主要体现在值传递和引用传递上

  • 不可变类型(int.float,str,tuple,frozenset)

传递方式为值传递:传递的是该对象的值,函数内部修改值不会影响外部变量的值

def modify(x):
    print('修改之前:', x, id(x))    #修改之前: 5 140722275297848
    x = 10  		# 修改了 x 的值,但不会影响外部变量
    print('修改之后:',x, id(x))     #修改之后: 10 140722275298008  在函数中重新开辟了一个空间对象赋给x

a = 5
modify(a)
print('原始数据:',a, id(a))          #原始数据: 5 140722275297848
  • 可变类型(list,dict,set等)

传递方式是引用传递:传递的是该对象的引用内存地址),在函数内部修改参数的内容会直接影响外部变量

def modify(lst):
    print('修改之前:', lst, id(lst))   #修改之前: [1, 2, 3] 2123053058816
    lst.append(4)  # 修改了 lst 对象的内容
    print('修改之后:',lst, id(lst))    #修改之后: [1, 2, 3, 4] 2123053058816   直接修改了对象的数据

a = [1, 2, 3]
modify(a)
print('外部原始数据:',a, id(a))        #外部原始数据: [1, 2, 3, 4] 2123053058816
  • 避免副作用

通过复制对象来避免课变类型的副作用:

列表:lst.copy()或切片list[:]来创建副本

字典:   dict.copy()copy.deepcopy()来进行深拷贝

例:

def modify(lst):
    lst_copy = lst.copy()  # 创建副本
    lst_copy.append(4)      # 修改副本

a = [1, 2, 3]
modify(a)
print(a)  # 输出: [1, 2, 3] (外部列表不受影响)
  • 浅拷贝:只复制对象的一层结构,新对象和原对象共享子对象,修改子对象会相互影响
  • 深拷贝:递归地复制对象的所有子对象,新对象和原对象完全独立,修改原对象不会影响新对象,反之亦然。

四.匿名函数

匿名函数即没有名字的函数,可以有任意数量的参数,但只能包含一个表达式,并返回该表达式的值

4.1基本语法

lambda argumens : expression

  • arguments:一个或多个输入参数,可以是位置参数或关键词参数。

  • expression:一个单一的表达式,它的值将作为返回值返回。

4.2使用场景

常与高阶函数如map(),filter()和sorted等一起使用

例:

numbers = [1, 2, 3, 4, 5]
# 使用 map() 将每个数字平方
squared_numbers = list(map(lambda x: x ** 2, numbers))

print(squared_numbers)  # 输出: [1, 4, 9, 16, 25]
4.3.条件表达式

在lambda中使用条件表达式(if-else)做决策

例: 注意even 与odd 的位置

# 判断是否为偶数
is_even = lambda x: "Even" if x % 2 == 0 else "Odd"

五.内置函数

python直接提供了大量的可直接使用的内置函数

官方地址:https://docs.python.org/zh-cn/3.13/library/functions.html

序号 函数 功能
1 all() 如果可迭代对象中所有元素为true则返回true,反之false
2 sum() 返回可迭代对象中所有元素的和
3 sorted() 返回一个新列表,其中包含可迭代对象中的元素,升序排列
4 reversed() 返回一个反向迭代器(将元素反向排列),可用list()转换为列表
5 callable() 检查对象是否可以被调用  print(callable(print))  # 输出: True
6 zip() 将迭代对象打包成一个元组,用于并行遍历多个序列
7 eval() 将字符串作python表达式执行,返回结果(字符串章节有详细介绍)
8 exec() 与7差不多
9 globals()和locals() globals() 返回当前全局符号表(一个字典);locals() 返回当前局部符号表(也是字典)。
10

filter()

从可迭代对象中过滤出符合条件的元素

六.高阶函数

高阶函数是指可以接受一个或多个函数作为参数,或者返回一个函数作为结果的函数

6.1map

语法:map(function, iterable)     iterable:可迭代对象

  • 接受一个函数和一个可迭代对象

  • 将接受的函数应用到可迭代对象的每个元素上

  • 返回一个包含结果的迭代器

numbers = [1, 2, 3, 4, 5]
squared = (list(map(lambda x: x**2, numbers)))
print(squared)   #[1, 4, 9, 16, 25]
6.2filter

语法:filter(function, iterable)

  • 接受一个函数和一个可迭代对象

  • 用接受的函数来筛选出可迭代对象中满足条件的元素    (用bool尔值来筛选)

  • 返回一个包含满足条件的元素的迭代器

numbers = [1, 2, 3, 4, 5]
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
# even_numbers现在包含[2, 4]
6.3reduce

语法:reduce(function, iterable, initializer)    initializer为初始值可有可无

  • reduce函数接受一个函数和一个可迭代对象

  • 将接受的函数累积地应用到可迭代对象的元素上

  • 可选的 $initializer$ 参数可以作为累积的初始值

from functools import reduce

numbers = [1, 2, 3, 4, 5]
product = reduce(lambda x, y: x * y, numbers)
# product现在包含120 (1 * 2 * 3 * 4 * 5)   120

七.变量作用域

变量作用域(scope)是指在程序中某个变量的有效范围

python中的变量作用域遵循legb规则(Local,Enclosing,Global,Built-in)

7.1.Local-局部作用域
  • 指函数或方法内部定义的变量。

  • 仅在函数内部有效,函数外部无法访问

  • 在函数调用时被创建,在函数调用后自动销毁

def fun():
    a=10  #局部变量
7.2.Enclosing
  • 指外层函数中的变量,在内层函数中可访问,但不可修改

  • 当一个函数嵌套在另一个函数内部时,外层函数的变量属于Enclosing作用域。

nonlocal:将局部作用域中变量声明为外部嵌套数作用域中的变量

               多个外层函数都存在相同变量选最近那个即可

#nonloca
def fun():
    x = 20
    def fun1():
        x = 30
        def fun2():
            nonlocal x
            return x
        return fun2
    return fun1


re = fun()()()   #此时必须用三次()显示三次调用   若只有单个()则表示调用fun1对象
print(re)        #30
#nonloca
def fun():
    x = 20
    def fun1():
        x = 30
        def fun2():
            nonlocal x
            return x
        return fun2()
    return fun1()


re = fun()
print(re)

上面俩段代码注意括号的使用

7.3.Global-全局作用域
  • 指模块级别定义的变量,整个模块都可以访问

  • 如果想在函数中修改全局变量,需要使用global关键字。

7.4.Built-in-内建作用域
  • 包含Python内建的函数、异常和常量,如print(), len(), int, Exception等。

  • 这些变量可以在任何地方使用

7.5.变量查找顺序

作用域遵循LEGB规则(Local, Enclosing, Global, Built-in) 即先后顺序

八.函数内存分配

  • 将函数的代码存储到代码区,函数体中的代码不执行
  • 调用函数时,在内存中开辟空间(栈帧),存储函数内部定义的变量
  • 函数调用后,栈帧立即被释放。(垃圾回收机制)

九.递归函数

递归是指函数直接或间接调用自身的过程。

9.1函数结构
  • 终止条件:用于确保递归能够停止避免无限递归

  • 递归调用:函数在其内部调用自身,传递简化或减少的参数,以解决更小的子问题。

9.2基本步骤
  • 定义递归函数:在函数体内调用函数自身。

  • 设定终止条件确保递归能终止

  • 逐步简化问题:通过传递较小的参数递归求解,直至终止条件满足。

9.3示例
#递归  阶乘
def fun(x):
    if x==0 or x==1:
        return 1
    return x*fun(x-1)  #逻辑上可理解为重新开辟一个定义域fun(x-1)

print(fun(5))          #120

你可能感兴趣的:(python,开发语言)