python基础总结(2)函数相关

本文详细介绍了Python中的函数概念、参数传递(位置参数、关键字参数、混合参数),以及形参、默认值、动态传参、global和nonlocal的作用,还涵盖了闭包、装饰器、迭代器、生成器、推导式、递归和二分查找等内容。
摘要由CSDN通过智能技术生成

函数

语法:
def 函数名(参数):
功能

参数

函数的参数包括形参和实参
形参没有确切的值
实参是在函数执行的时候给函数传递具体的值

实参的几种类型

1、位置参数,按照一一对应的关系给形参传递数据

def func(a,b,c):
    print(a,b,c)

func(11,22,33)

2、关键字参数,按照形参的名字进行传递数据

def func(a,b,c):
    print(a,b,c)

func(a =11,c =22,b =33)

3、混合参数(位置参数+关键字参数),注意顺序,位置参数在前关键字参数在后

def func(a,b):
    print(a,b)

func(11,b=12)

应注意:
形参在执行的时候必须要有明确的数据,否则会报错,多了少了都会报错
形参的数量必须和实参的数量一致

形参

def func(name,age,gender="男"):   # 形参给值的话,不指定实参就默认,指定了就用指定的值
    print("录入姓名",name)
    print("录入年龄",age)
    print("录入性别",gender)

func("张三",18)
func("王五",19,"女")

如果默认值是可变的数据类型,会被共享

动态传参

动态传参:给出多个参数,在形参位置一次性接收
*动态接收位置参数,自动打包成元组

def chi(*food):
    print(food)

chi("饭","汤","菜")

**动态传参之关键字传参,返回字典

def chi(**food):
    print(food)


chi(主食="大米",汤="大米汤",甜品="大米饼子")

位置参数,默认值参数,动态传参三种形参
如果要混合使用那么正确顺序:位置参数>*args>默认值参数>**kwargs

总结

*和**的作用
再形参中表示聚合,把位置参数聚合成元组,把关键字参数聚合成字典
在实参中表示打散,把可迭代对象转化为位置参数,把字典转化成关键字参数

global和nonlocal

由于在python里边不允许在函数内部更改外部变量数据,所以需要在函数内部更改外部变量数据的时候就需要用到global和nonlocal

global

首先有错误示范

a = 10
def func():
    a = a + 1
    print(a)
func()
# 错误原因:不能直接在函数内部修改外部变量

正确做法

a = 10
def func():
    global a   # 把全局内容引入局部
    a = a + 1
    print(a)
func()
print(a)   # 函数外部的a变量的值也发生了更改

nonlocal

可以在嵌套函数中使用来修改外部变量
例如

a = 10
def func1():
    def func2():
        nonlocal a
        a = a + 1
        print(a)

闭包

概念:内层函数对外层函数变量的使用
作用1:可以让一个变量封锁起来,外界能看到但不能修改,是变量很安全
作用2:可以让一个变量常驻内存
例如

def func():
    a =10
    def inner():
        print(a)
        return a
    return inner
fn = func()
b = fn()

小型闭包,定义函数func

def func():
    a = 10
    def inner():
        print(a)
    inner()

func()

函数名的本质是变量,变量能干的函数名都能干

装饰器

装饰器的作用:在不改变原有代码的基础上,给函数新增功能,可以在原有操作后面或者前面随意新增新的功能

简单的装饰器

# 简单的装饰器
def wrapper(fn):
    def inner():
        print("执行目标函数之前")
        fn()
        print("执行目标函数之后")
    return inner

@wrapper  # 相当于add = wrapper(add)
def add():
    print("我是add")

# add = wrapper(add)
add()

有参数的装饰器

如果要处理有参数的装饰器,使用动态传参*args(动态位置传参返回元组),**kargs(动态关键字传参返回字典)

def wrapper(fn):
    def inner(*args,**kargs):   # 会将参数聚合为元组和字典
        print("good")
        fn(*args,**kargs)       # 将聚合成元组和字典的参数打散为普通参数
        print("very,good")
    return inner

@wrapper
def add(haha,heihei):
    print(f"我想说{haha},也想说{heihei}")


add("你是好样的","孩子你无敌了")

有返回值的装饰器

def wrapper(fn):
    def inner():
        print("good")
        ret = fn()
        print("well")
        return ret
    return inner

@wrapper
def add():     # 本质上在执行inner()函数,由于inner()函数没有返回值,所以出现空值
    print("你好")
    return "你也好"
ret = add()
print(ret)

通用装饰器

以上两个问题的综合,通用装饰器的写法

def wrapper(fn):
    def inner(*args,**kargs):
        print("之前")          # 执行目标函数之前
        ret = fn(*args,**kargs)
        print("之后")          # 执行目标函数之后
        return ret
    return inner

@wrapper
def add():
    print('hh')
    return "huh"

高阶装饰器

同一个函数被多个装饰器装饰

def wrapper1(fn):
    def inner(*args,**kwargs):
        print("wrapper1-before")
        ret = fn(*args,**kwargs)
        print("wrapper1-after")
        return ret
    return inner

def wrapper2(fn):
    def inner(*args,**kwargs):
        print("wrapper2-before")
        ret = fn(*args,**kwargs)
        print("wrapper2-after")
        return ret
    return inner

def wrapper3(fn):
    def inner(*args,**kwargs):
        print("wrapper3-before")
        ret = fn(*args,**kwargs)
        print("wrapper3-after")
        return ret
    return inner

@wrapper3
@wrapper2
@wrapper1    # 按照就近原则来装饰
def target():
    print("我是target")

target()

迭代器

迭代器的作用是统一了容器类型循环遍历的标准
容器类型有列表、字典、字符串、元组、集合
int类型的数据和bool类型的数据不能被迭代
所有可迭代对象的内部都用一个__iter__的功能 iterable可迭代的iterator迭代器
使用__iter__()拿到相应的迭代器


使用步骤:
1.通过__iter__拿到对应迭代器
2.通过__next__拿到元素
3.重复第二步,反复执行,直到出现了StopIteration


想要重头拿数据需要重新获得迭代器
不适合运用数学上的等价代换
还可以使用iter()函数拿到迭代器,同样的还有next()函数

例如

lst = [11,22,33]
it = iter(lst)
print(next(it))    # 括号内放的是it就是获取迭代器的过程
print(next(it))
print(next(it))    

# 迭代器可以for循环

生成器

生成器的本质是迭代器
当函数内部有yield时,他就是一个生成器函数,yield也有返回的意思
基本形式如下

def func():
    print("哈哈")
    yield "你好"


ret = func().__next__()
print(ret)

生成器表达式

g = (i for i in range(10))

print(g.__next__())

# 把生成器拿空
# 1.for循环
for item in g:
    print(item)
# 2.用list,tuple,set拿空数据
print(list(g))

总结

1、生成器函数中有yield
2、生成器函数执行时,实际上创建了一个生成器
3、必须要用__next__()来执行下一段代码,会自动执行到下一个yield结束
4、yield也有返回的意思,可以让一个函数分段执行
5、当后面没有filed的时候,再次__next__()会报错StopIteration
6、生成器的最大作用是节省内存

推导式

python内有列表推导式,字典推导式,集合推导式,但没有元组推到式

列表推导式

基本语法:[结果 for循环 if条件]

# 将所有的奇数添加到列表
lst = [i for i in range(1,11) if i%2 == 1]
print(lst)

字典推导式

基本语法:{key:value for循环 if}

lst = ["王","张","李"]
dit = {i:lst[i] for i in range(len(lst))}
print(dit)

集合推导式

基本语法:{key for循环 if}

lambda匿名函数

匿名函数又叫做lambda表达式
语法:lambda 参数:返回值
要求:
1.函数的参数可以是多个,但参数之间要用逗号隔开
2.匿名函数不管有多复杂,只能写一行,且逻辑结束后必须要返回数据
3.返回值可以是任意是数据类型,和其他函数一样。
4.如果要返回不只一个结果,那么要手动添加小括号变成元组一起返回

fn = lambda n:n**2
ret = fn(100)
print(ret)

fn = lambda a,b:a+b
print(fn(1314,521))

python内置函数

Python解释器目前内置的所有函数(71个):内置函数 — Python 3.12.3 文档


简要介绍一些内置函数
1、

dir()可以查看一个数据类型能够进行哪些操作
callable(xxx)判断xxx是否能够被调用,返回bool值
help()函数查看源码
动态导入__import__()动态导入一个模块
文件操作相关open("文件名",mode="",encoding="utf-8"),一般使用with open
内存相关id()查看内存地址,hash()可以查看哈希值

2、字符串类型代码的执行相关函数

s = "1+1"
ret = eval(s)  eval()可以把字符串当作代码执行并且能返回值
print(ret)

s = "a = 100"
exec(s)        exec()也可以把字符串当作代码执行但是没有返回值
print(a)

compile()可以把一段代码加载,后面可以通过exec()和evel()去执行
基本格式和语法为   compile("代码","文件名字","执行方式")最后的执行方式
exec是没有返回值,evel是有返回值,signal应对有交互式的代码

3、进制转换函数

bin()二进制
oct()八进制
hex()十六进制   0-f

4、数学符号运算

abs()求绝对值
divmod()除法  结果(商,余数)
round()四舍五入
pow()次幂计算
sum()  ()内是可迭代对象
max()
min()
enumerate() 枚举,可以拿到索引和元素
any() 将可迭代对象按照or连接
all() 将可迭代对象按照and连接
zip() 拉链函数,有水桶的短板效应。可以快速构建列表

5、序列相关

reversed() 可以把列表翻转,返回迭代器
slice() 切片

6、字符串相关

ord()  把字串转化成数字
chr()  把数字转化成字符

7、

sorted()排序函数 由于字符串类型的数据没法正常排序,所以可以指定排序方式进行排序,其格式为sorted(可迭代对象 key="定义的排序方式" reserve)
filter()筛选函数  其格式为filter(function  可迭代对象) 返回值是迭代器
map()映射函数,可以让可迭代对象中的每一项元素都做相同的操作,格式是map(function 可迭代对象)常用于较为复杂的函数

递归

递归的本质就是函数自己调用自己
递归方法解决汉诺塔问题(https://baike.baidu.com/item/汉诺塔问题/1945186?fr=ge_ala)

# 将n-1层铁饼从A经过C移动到B
# 再将A铁饼移动到C
# 最后将铁饼从B经过A移动到C
def honio(n,a,b,c):
    if n>0:
        honio(n-1,a,c,b)
        print(f"{a}移动到{c}")
        honio(n-1,b,a,c)
honio(3,"A","B","C")

二分法

二分法只适用于有序的序列查找内容,优点是可以大幅度提高程序运行效率

lst = [1,2,3,25,36,37,58,69,547]
n = int(input("查找"))
left = 0
right = len(lst)-1
while left<=right:
    mid = (left+right)//2
    if n < lst[mid]:
        right = mid-1
    elif n > lst[mid]:
        left = mid+1
    else:
        print("找到了",mid)
        break
else:
    print("没找到")

下一篇会总结一下常用的模板 

由于个人总结的局限性,所以总结可能不会不太完整,甚至有些地方不会太准确,欢迎大佬指正或者补充

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值