函数的进阶

1. 可变长参数

(1)可变长形参

*args

用来接收多余的位置实参,args是人们约定俗成的一种写法。他把接收到的值按元组的形式存储。
这里args不是形参名,因为当有关键字实参为 args = 1 时,若形参中没有 args这个形参,则调用函数时会报错
也就是说  args = (a,b,c,d)  这样的形式
当没有任何实参传来时,程序不会报错,args就是空元组: args = ()


**kwargs

用来接收多余的关键字实参,kwargs也是人们约定俗成的一种写法。他把接收到的值按字典的形式存储。
这里kwargs不是形参名,因为当有关键字实参为 kwargs = 1 时,若形参中没有 kwargs这个形参,则调用函数时会报错
也就是说  kwargs = {'a':1,'b':2,'c':3,'d':4}  这样的形式
当没有任何实参传来时,程序不会报错,kwargs就是空元字典: kwargs = {}

*args 和 **kwargs 一起使用就可以接收全部的实参

(2)可变长实参

*
用来把星号后的容器数据类型(列表,元组,集合)中的数据提取出来,依次传给位置形参

**
用来把星号后的字典中的键值对提取出来转化成关键字实参,依次传给和关键字对应的形参

2. 函数的对象

python中一切皆对象

对象能够完成这四件事情

  1. 能被引用

  2. 当作容器类数据类型的元素

  3. 当作函数的实参

  4. 当作函数的返回值

def register():
    print('register')


def login():
    print('login')


def withdraw():
    print('wightdraw')


def shopping():
    print('shopping')


func_dict = {
    '1': register,
    '2': login,
    '3': withdraw,
    '4': shopping,
}

print('''
1 注册
2 登录
3 提现
4 购物
''')

while True:
    choice = input('请选择你需要的功能(输入q退出):')
    if choice == 'q':
        break
    func_dict[choice]()    #此时的 func_dict[chioce] 相当于上面的各个函数名,可以加个括号对上面的函数进行调用

3. 函数的嵌套

函数的嵌套就是函数里面有函数

函数内部定义的函数,外部不能直接调用

#定义函数,只检测语法,不会执行代码
def f1():
    print('from f1')
    def f2():
        print('from f2')
    f2() # 在同一位置时,调用函数必须放在定义之后

res = f1()

4. 名称空间和作用域

变量名/函数名/内置方法名 都存放在名称空间

1. 名称空间

  • 名称空间的生成顺序:
    1. 内置名称空间:python解释器启动的时候就有了
    2. 全局名称空间:执行文件代码的时候才会有全局
    3. 局部名称空间:函数调用的时候才会有局部
  • python解释器搜索名称的顺序:

    先从当前位置寻找,找不到再按照下面的这种顺序;搜索不会按下面的逆序搜索(只会在当前或者然继续搜索)

    局部 ——》全局——》内置——》报错

(1)内置名称空间

  • 存储了python解释器自带内置方法(print/len/list/str/dict 等)的名称

(2)全局名称空间

  • 存储了除了内置和局部名称的其他名称

(3)局部名称空间

  • 函数内部定义的都叫局部

  • 局部名称空间存储了局部中的各名称

2. 作用域(发挥作用的区域)

(1)全局作用域

包含:内置名称空间 + 全局名称空间

(2)局部作用域

只包含:局部名称空间

3. 改变全局和局部的三种方法

  • 1. 全局作用域的 x 和局部作用域的 x 没有半毛钱的关系
    
    2. 局部作用域1的x和局部作用域2的x也没有任何关系,即使局部作用域1和局部作用域2再同一个局部作用域下

(1)可变数据类型无所不能

  • 要用就用可变数据类型
  • 但不能以定义的方式改变该数据类型
#所有可变数据类型均可打破上述一切规则

lt = [10]
def f1():
   lt.append(12)
#  lt = [0]   这种方法不行
   lt[0] = 11

f1()
print(lt) # 打印结果: lt 为 [11,12]

(2)global

  • global 将局部名称变成全局名称
x = 10
def f1():
   global x  # 让global以下的局部的x变成全局的x
   x = 20

f1()
print(x) # 打印结果:x为20

(3)nonlocal

  • nonlocal 将当前局部名称变成本层的顶层局部名称
x = 10

def f1():
   def f2():
      def f3():
           nonlocal x  # nonlocal让x成为顶层函数的局部,不是让他成为全局  # 压根没有应用情景,尽量不要嵌套函数
           x = 1
       x = 2
       f3()
       print(x) #  打印结果: x为1
    
02-12 10:06