暑期实践第十四天 2022-7-17

今日学习进度:函数相关

1.收集参数

收集参数,就是说只指定一个参数,然后允许调用函数时传入任意数量的参数。

定义收集参数其实也很简单,即使在形参的前面加上星号(*)来表示:
 

def myfunc(*arg):
    print(f"这个参数有{len(arg)}个")
    print(f"第二个参数为{arg[1]}")

    
myfunc(1, 2, 3, 4, 5)
这个参数有5个
第二个参数为2

如果在收集参数后面还需要指定其它参数,那么在调用函数的时候就应该使用关键参数来指定后面的参数:

>>> def myfunc(*args, a, b):
...     print(args, a, b)
... 
>>> myfunc(1, 2, 3, a=4, b=5)
(1, 2, 3) 4 5

除了可以将多个参数打包为元组,收集参数其实还可以将参数们打包为字典,做法呢,是使用连续的两个星号(**):

>>> def myfunc(**kwargs):
...     print(kwargs)
... 

对于这种情况,在传递参数的时候就必须要使用关键字参数了,因为字典的元素都是键值对嘛,所以等号(=)左侧是键,右侧是值:

>>> myfunc(a=1, b=2, c=3)
{'a': 1, 'b': 2, 'c': 3}

混合起来使用就更加灵活了:

>>> def myfunc(a, *b, **c):
...     print(a, b, c)
... 
>>> myfunc(1, 2, 3, 4, x=5, y=6)
1 (2, 3, 4) {'x': 5, 'y': 6}

2.解包参数

一个星号(*)和两个星号(**)不仅可以用在函数定义的时候,在函数调用的时候也有特殊效果,在形参上使用称之为参数的打包,在实参上的使用,则起到了相反的效果,即解包参数:

>>> args = (1, 2, 3, 4)
>>> def myfunc(a, b, c, d):
...     print(a, b, c, d)
... 
>>> myfunc(*args)
1 2 3 4

那么两个星号(**)对应的是关键字参数:

>>> args = {'a':1, 'b':2, 'c':3, 'd':4}
>>> myfunc(**args)
1 2 3 4

3.局部作用域

如果一个变量定义的位置是在一个函数里面,那么它的作用域就仅限于函数中,我们将它称为局部变量。

>>> def myfunc():
...     x = 520
...     print(x)
... 
>>> myfunc()
520

变量 x 是在函数 myfunc() 中定义的,所以它的作用域仅限于该函数,如果我们尝试在函数的外部访问这个变量,那么就会报错:
 

>>> print(x)
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    print(x)
NameError: name 'x' is not defined

4.全局作用域

如果是在任何函数的外部去定义一个变量,那么它的作用域就是全局的,我们也将其称为全局变量:

>>> x = 880
>>> def myfunc():
...     print(x)
... 
>>> myfunc()
880

如果在函数中存在一个跟全局变量同名的局部变量,在函数中,局部变量就会覆盖同名的全局变量的值:

>>> x = 880
>>> def myfunc():
...     x = 520
...     print(x)
... 
>>> myfunc()
520
>>> print(x)
880

注意:代码中两个 x 并非同一个变量,只是由于作用域不同,它们同名但并不同样。
 

5.global语句

通常我们无法在函数内部修改全局变量的值,除非使用 global 语句破除限制:

>>> x = 880
>>> def myfunc():
...     global x
...     x = 520
...     print(x)
... 
>>> myfunc()
520
>>> print(x)
520

6、嵌套函数

>>> def funA():
...     x = 520
...     def funB():
...         x = 880
...         print("In funB, x =", x)
...     print("In funA, x =", x)

在外部函数 funA() 里面嵌套了一个内部函数 funB(),那么这个内部函数是无法被直接调用的:

>>> funB()
Traceback (most recent call last):
  File "<pyshell#23>", line 1, in <module>
    funB()
NameError: name 'funB' is not defined

想要调用 funB(),必须得通过 funA()

>>> def funA():
...     x = 520
...     def funB():
...         x = 880
...         print("In funB, x =", x)
...     funB()
...     print("In funA, x =", x)
... 
>>> funA()
In funB, x = 880
In funA, x = 520

通常我们无法在嵌套函数的内部修改外部函数变量的值,除非使用 nonlocal 语句破除限制:

>>> def funA():
...     x = 520
...     def funB():
...         nonlocal x
...         x = 880
...         print("In funB, x =", x)
...     funB()
...     print("In funA, x =", x)
... 
>>> funA()
In funB, x = 880
In funA, x = 880

注:只能更改相邻的外部函数

def funa():
    x = 520
    def funb():
        x = 666
        def func():
            nonlocal x
            x = 880
            print("In func, x =", x)
        func()
        print("in funb, x =", x)
    funb()
    print("in funa, x =", x)

    
funa()
In func, x = 880
in funb, x = 880
in funa, x = 520

7.LEGB原则

其中:
 

  • L 是 Local,是局部作用域
  • E 是 Enclosed,是嵌套函数的外层函数作用域
  • G 是 Global,是全局作用域
  • B 是 Build-In,也就是内置作用域

从左至右依次覆盖,B最容易被覆盖

>>> str = "1111"
>>> str(520)
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    str(520)
TypeError: 'str' object is not callable

它本来的功能是将参数转换成字符串类型,但由于我们将它作为变量名赋值了,那么 Python 就把它给覆盖了.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值