zoukankan      html  css  js  c++  java
  • 函数基础2

    *与**在形参与实参中的应用

    一.可变长指的是参数的个数不固定
    站在实参的角度,实参是用来为形参来赋值的,如果实参的个数不固定,那么必须要有对应的形参能够接收溢出实参
    =在形参中用*与**=

    1.1在形参名前加*,
    def func(x,*y):  # y=(2,3)
       print(x)
       print(y)
    
    func(1,2,3)
    func(1)
    func()  #位置形参x必须被传值
    

    示范:

    def add(*nums):
       res = 0
       for num in nums:
          res+=num
          return res
    
    res = add(1,2,3)
    print(res)
    
    1.2在形参名前加:会把溢出的关键字实参存成字典,然后赋值其后的形参名
    def func(x,**y):  #y=(2,3,4)
       print(x)
       print(y)
    func(1,a=111,b=222,c=333)
    func(a=111,b=222,x=1,c=333)
    

    在实参中用*与**=

    def func(x, y, z):
    print(x, y, z)

    1.3在实参前加:会把其后的值打散成位置实参
    nums = [1,2,3]
    func(*nums) # func(1,2,3)
    
    1.4在实参前加:会把其后的值打撒关键字实参
    dic = {"y": 111, "z": 222, "x": 333}
    func(**dic)  # 333 111 222
    

    =======在形参与实参中混用*与**

    def index(x,y,z,a,b,c):
       print("index=======>",x,y,z,a,b,c)
    
    def wrapper(*args,**kwargs):
       index(*args,**kwargs)    # args=(1, 2, 3,)   kwargs={"a":111,"b":222,"c":333}
    wrapper(1,2,3,a=111,b=222,c=333)   # index(*(1, 2, 3,),**{"a":111,"b":222,"c":333})
    
                            #  index(1,2,3,c=333,b=222,a=111)
    
    wrapper(1,2,3,a=111,b=222,c=333)
    

    命名关键字形参

    def func(x, y=222, *args, n=777,m, **kwargs):  # m,n必须按照关键字实参的格式为其赋值
        print(x)  # 1
        print(y)  # 2
        print(args)  # (3,4,5)
        print("m===>", m)
        print("n===>", n)
        print(kwargs)
    
    func(1,2,3,4,5,6666666)
    func(1,2,3,4,5,m=6666666)
    func(1, 2, 3, 4, 5, n=88888,m=6666666, a=11, b=22, c=33)
    

    函数对象:

    函数对象指的是函数可以被当成变量去使用

    def foo(): # foo = 函数的内存地址
    print("from foo")

    可以被赋值
    f = foo
    print(f is foo)
    f()
    
    可以当做参数传给一个函数
    
    def bar(func):
       print(func)
       func()
    
    bar(foo)
    
    可以当成一个函数的返回值
    
    
    def bar(func):
       return func
    
    res = bar(foo)
    print(res)
    
    可以当成容器类型的元素
    l = [foo]
    print(l)
    l[0]()
    

    示例:

    def login():
       print("登录功能.....")
    
    
    def withdraw():
       print("提现功能.....")
    
    
    def transfer():
       print("转账功能.....")
    
    
    def recharge():
       print('充值功能......')
    
    
    func_dic = {
       "1": [login, "登录"],
       "2": [withdraw, "提现"],
       "3": [transfer, "转账"],
       "4": [recharge, "充值"]
    }
    
    while True:
       print("0    退出")
       for k in func_dic:
          print(f"{k}    {func_dic[k][1]}")
    
       choice = input("请输入你的指令编号:").strip()
    
       if choice == "0":
          break
       if choice in func_dic:
          func_dic[choice][0]()
       else:
          print('输入的指令不存在')
    

    函数嵌套:

    函数的嵌套调用

    def bar():
       print('from bar')
    
    
    def foo():
       print('from foo')
       bar()
    
    
    foo()
    

    案例:

    def max2(x, y):
       if x > y:
          return x
       else:
          return y
    
    
    def max4(a, b, c, d):
       res1 = max2(a, b)
       res2 = max2(res1, c)
       res3 = max2(res2, d)
       print(res3)
    
    
    max4(1, 2, 3, 4)
    

    函数的嵌套定义

    def f1():
       print('from f1')
    
       # f2 = 函数的内存地址
    
       def f2():
          print("from f2")
    
    
    f1()
    

    定义在函数内的函数特点是: 正常情况只能在函数体内调用

    from math import pi
    
    
    def circle(radius, mode=0):
       def perimeter(radius):
          return 2 * pi * radius
    
       def area(radius):
          return pi * (radius ** 2)
    
       if mode == 0:
          return perimeter(radius)
       elif mode == 1:
          return area(radius)
    
    
    res1 = circle(3, 0)
    res2 = circle(3, 1)
    print(res1)
    print(res2)
    
    
    def func():
       x = 10
       print(x)
    
       def f2():
          print('from f2')
    
       f2()
    
    
    func()
    
    # print(x)
    

    名称空间与作用域

    名称空间: 就是存放名字的地方
    1.
    内置名称空间: 存放的是内置的名字, 如printinputlen
    生命周期: 解释器启动则产生, 解释器关闭则销毁
    2.
    全局名称空间: 存放的是顶级的名字
    生命周期: python程序运行时则产生, python程序结束时则销毁

    x = 10
    
    
    def func():
       x = 111
       print(x)
    
    
    if 1:
       y = 666
    

    局部名称空间: 函数内的名字
    生命周期: 调用函数时则产生, 函数调用结束则销毁

    名字的查找优先级:
    从当前位置往外查找, 如果当前是在局部: 局部名称空间->全局名称空间->内置名称空间
    从当前位置往外查找, 如果当前是在全局: 全局名称空间->内置名称空间

    示范1:

    def func():
       len = 222
    
    
    # print(len)
    
    func()
    print(len)
    

    名称空间可以理解为一层套一层的关系, 问题是嵌套关系是在函数定义阶段生成的, 还是在函数调用阶段生成的?

    x = 111
    
    
    def foo():
       print(x)
    
    
    def bar(f):
       x = 222
       f()
    
    
    bar(foo)
    

    一个非常重要的结论: 名称空间的嵌套关系是函数定义阶段(即扫描语法时)
    就固定死的, 与函数的调用位置无关

    x = 111
    
    
    def func():
       print(x)  # 报错
       x = 222
    
    
    func()
    

    练习

    x = 0
    
    
    def f1():
       x = 1
    
       def f2():
          x = 2
          print(x)
    
       f2()
    
    
    f1()
    
    len = 111
    
    len = 111
    
    
    def f1():
       len = 222
    
    
    def f2():
       len = 333
    
    
    f1()
    f2()
    

    全局范围 / 全局作用域: 内置名称空间 + 全局名称空间
    特点: 全局存活, 全局有效
    局部范围 / 局部作用域: 局部名称空间
    特点: 临时存活, 局部有效

    global与nonlocal
    案例1

    x = 10
    
    
    def func(x):  # x = 10的内存地址
       x = 10
       的内存地址
       x = 20
    
    
    func(x)  # func(值10的内存地址)
    print(x)
    

    案例2

    x = [11, 22, 33]
    
    
    def func(x):  # x = 列表[11,22,33]的内存地址
    
       # x = 列表[11,22,33]的内存地址
    
       # x=444444444444
    
       x[0] = 66666
    
    
    func(x)  # func(列表[11,22,33]的内存地址)
    print(x)
    

    案例3

    x = [11, 22, 33]
    
    
    def func():
       x[0] = 66666
    
    
    func()
    print(x)
    

    案例4

    x = 10
    
    
    def func():
       global x
       x = 22
    
    
    func()
    print(x)
    

    案例5: nonlocal生命名字是来自于外层函数的(***)

    x = 10
    
    
    def f1():
       x = 111
    
       def f2():
          nonlocal x
          x = 222
    
       f2()
       print(x)
    
    f1()
    print(x)
    
  • 相关阅读:
    Eclipse常见配置及常用插件
    杂记
    表单双引号问题
    兼容ie的jquery ajax文件上传
    Markdown 學習
    jstl c标签
    java 在接口里函数不能重载?
    【转】Eclipse里项目名有红叉,但是展开后里面又没有红叉叉
    Android性能优化之一:ViewStub
    Merge用法
  • 原文地址:https://www.cnblogs.com/lgh8023/p/13346649.html
Copyright © 2011-2022 走看看