2024年学Python 函数从青铜到王者_python学到函数是什么进度(4)

本文详细介绍了Python中的函数参数类型(关键字参数、默认参数、不定长参数),作用域规则(LEGB),以及装饰器和闭包的概念。通过实例展示了如何使用这些概念进行编程实践。
摘要由CSDN通过智能技术生成
def get_info(name, age):
    print("My name is %s, I'm %d years old." %(name, age))
 
get_info('tom',25)
get_info('jerry',16)

```
+ 关键字参数:关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值

 
```
def get_info(name, age):
    print("My name is %s, I'm %d years old." %(name, age))
 
# get_info(16, 'jerry')      # TypeError: %d format: a number is required, not str
get_info(age=16, name='jerry')  # My name is jerry, I'm 16 years old.

```
+ 默认参数:调用函数时,默认参数的值如果没有传入,则被认为是默认值

 
```
def get_info(name, age, sex='male'):
    print('Name: %s' %name)
    print('age: %d' %age)
    print('Sex: %s' %sex)
 
get_info('tom',23)
get_info('jerry',30,'female

```
+ 不定长参数:你可能需要一个函数能处理比当初声明时更多的参数

 
```
# def add(x, y):
#     return x + y
 
def add(*tuples):
    sum=0
    for v in tuples:
        sum += v
    return sum
 
print(add(1,4,6,9))         # 20
print(add(1,4,6,9,5)) 


```
  • 参数的位置优先级

    • 关键字参数
    • 默认参数
    • args不定长参数
    • kwargs不定长参数
5. 函数的作用域
  • Python中的作用域分4种情况:

L:local,局部作用域,即函数中定义的变量;

E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的;

G:globa,全局变量,就是模块级别定义的变量;

B:built-in,系统固定模块里面的变量。

  • 搜索变量的优先级顺序依次是:
    作用域局部 > 外层作用域 > 当前模块中的全局 > python内置作用域,也就是LEGB。
x = int(2.9)  # int built-in
 
g_count = 0  # global
def outer():
    o_count = 1  # enclosing
    def inner():
        i_count = 2  # local
        print(o_count)
    # print(i_count) # 找不到
    inner() 
outer()
 
# print(o_count) # 找不到
当然,local和enclosing是相对的,enclosing变量相对上层来说也是local

  • 作用域的产生

在Python中,只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如if、try、for等)是不会引入新的作用域的,如下代码

if 2 > 1:
    x = 1
print(x)  # 1

这个是没有问题的,if并没有引入一个新的作用域,x仍处在当前作用域中,后面代码可以使用

def test():
    x = 2
print(x)    # NameError: name 'x2' is not defined

def、class、lambda是可以引入新作用域的

  • ***变量的修***改
x = 6
def f2():
    print(x)
    x = 5
f2()
  
# 错误的原因在于print(x)时,解释器会在局部作用域找,
# 会找到x = 5(函数已经加载到内存),但 x 使用在声明前了,所以报错:
# local variable 'x' referenced before assignment.
# 如何证明找到了x=5呢?简单:注释掉 x=5,x=6
# 报错为:name 'x' is not defined
# 同理

x = 6
def f2():
    x+=1    # local variable 'x' referenced before assignment.
f2()

  • global关键字

当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了,当修改的变量是在全局作用域(global作用域)上的,就要使用global先声明一下,代码如下\

count = 10
def outer():
    global count
    print(count) 
    count = 100
    print(count)
outer()

  • nonlocal关键字

global 关键字声明的变量必须在全局作用域上,不能嵌套作用域上,当要修改嵌套作用域(enclosing作用域,外层非全局作用域)中的变量怎么办呢,这时就需要nonlocal关键字了

def outer():
    count = 10
    def inner():
        nonlocal count
        count = 20
        print(count)
    inner()
    print(count)
outer()



  • 总结
变量查找顺序:LEGB,作用域局部>外层作用域>当前模块中的全局>python内置作用域;
只有模块、类、及函数才能引入新作用域;
对于一个变量,内部作用域先声明就会覆盖外部变量,不声明直接使用,就会使用外部作用域的变量;
内部作用域要修改外部作用域变量的值时,全局变量要使用global关键字,嵌套作用域变量要使用nonlocal关键字。nonlocal是python3新增的关键字,有了这个 关键字,就能完美的实现闭包了。

在这里插入图片描述

Python 高级函数

1.嵌套函数
  • 嵌套
def bar():
    print('in the bar')


def foo(func):
    print('in the foo')

    def inner():
        return func()

    return inner


foo(bar)
# foo(bar)()

2.装饰器之不带参数的func
  • 被装饰的函数
def decorative(func):
    def wrapper():    # 定义一个包装器
        print("Please say something: ")
        func()        # 调用func,这个func是我们自己定义的
        print("No zuo no die...")
    return wrapper

@decorative    # 使用@符号调用装饰器
def show():    # 定义func,名字取什么都无所谓,它只是用来传给装饰器中的func参数
    print("I'm from Mars.")

show()

3. 装饰器之带参数的func
  • 被装饰的函数
def decorative(func):
    def wrapper(x):
        print("Please say something...>")
        func(x)
        print("no zuo no die...")
    return wrapper

@decorative
def show(x):
    print(x)

show("hello,mars.")

3.有参数的装饰器
  • 一个参数的装饰器
def foo(func):
    def inner(arg):
        # 验证
        return func(arg)
    return inner

@foo
def bar(arg):
    print('bar')

  • 两个参数的装饰器
def foo(func):
    def inner(arg1,arg2):
        # 验证
        return func(arg1,arg2)
    return inner

@foo
def bar(arg1,arg2):
    print('bar')

  • 三个参数的装饰器
def foo(func):
    def inner(arg1,arg2,arg3):
        # 验证
        return func(arg1,arg2,arg3)
    return inner

@foo
def bar(arg1,arg2,arg3):
    print('bar')

  • 不固定参数的装饰器
def foo(func):
    def inner(*args,**kwargs):
        # 验证
        return func(*args,**kwargs)
    return inner
 
@foo
def bar(arg1,arg2,arg3):
    print('bar')

  • 一个函数可以被多个装饰器装饰
def foo(func):
    def inner(*args,**kwargs):
        # 验证
        return func(*args,**kwargs)
    return inner
 
def foo1(func):
    def inner(*args,**kwargs):
        # 验证
        return func(*args,**kwargs)
    return inner
 
 
@foo
@foo1
def bar(arg1,arg2,arg3):
    print('bar')

在这里插入图片描述

4.装饰器案例
  • 为函数添加致谢时间的装饰器函数


![img](https://img-blog.csdnimg.cn/img_convert/e66061119946ea19a317570745f0400a.png)
![img](https://img-blog.csdnimg.cn/img_convert/408444a112a07a6f455a40407616686e.png)
![img](https://img-blog.csdnimg.cn/img_convert/b5760a64ccdc707f82a48d0518a4f17e.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**

***为函数添加致谢时间的装饰器函数***

 

[外链图片转存中…(img-v1qFhJ7m-1714664839484)]
[外链图片转存中…(img-qrguD2UP-1714664839484)]
[外链图片转存中…(img-BiafgsqO-1714664839485)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值