• 函数对象,函数嵌套,名称空间


    一、定义函数的三种方式

      1、空函数:可以快速帮助你构建项目框架,使项目架构清晰明了(应用频率非常高)

    # 购物车功能
    def register():
        pass
    def login():
        pass
    def shopping():
        pass
    def pay():
        pass
    

      2、无参函数

    def func():
        print('from func')
    

      3、有参函数

    def func(x,y,*args,**kwargs):
        pass
    

      

    二、命名关键字参数(了解)

      在函数定义阶段,写在*与**可变长参数之间的形参,在给关键字参数传值的时候,只能用关键字为其传值,在定义阶段,给你感觉好像是z是默认值参数,放在了m这个未知参数的前面,应该报错,其实z和m都是命名关键字参数,不是默认值参数和位置参数

    def func(x, y = 1, *args, z = 3, m, **kwargs):
        print(x, y)
        print(args)
        print(z, m)
        print(kwargs)
    func(1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, z = 99, m = 999, o = 9999, i = 99999)
    

      

    三、函数对象

    函数时第一类对象:函数名指向的值可以被当做参数传递

    1、函数名可以被传递

    # 变量值的传递
    name = 'jason'
    x = name
    print(x)
    print(id(name))
    print(id(x))
    # 输出
    jason
    45859872
    45859872
    
    # 函数名指向的值的传递
    def func():
        print("from func")
    f = func
    print(f)
    print(func)
    print(id(f))
    print(id(func))
    # 输出
    <function func at 0x02BBA660>
    <function func at 0x02BBA660>
    45852256
    45852256
    

      2、函数名可以被当做参数传递给其他函数

    def func():
        print("from func")
    def index(args):
        print(args)
        print("from index")
    index(func)
    # 输出
    <function func at 0x0096A660>
    from func
    from index
    

      3、函数名可以被当做函数的返回值

    def index():
        print("index")
    def func():
        print("func")
        return index
    res = func()
    print(res)
    res()
    # 输出
    func
    <function index at 0x0295A660>
    index
    

      4、函数名可以被当做容器类型的参数

    def func():
        print("func")
    print(func())
    l = [1, 2, func, func()]
    print(l)
    # 输出
    func
    None
    func
    [1, 2, <function func at 0x00DEA660>, None]
    

      

    四、函数的嵌套调用

      在函数内部调用其他函数,可以将复杂的逻辑简单化

    def index():
        func()
        print("index")
    def func():
        print("func")
    index()
    # 输出
    func
    index
    
    # 比较4个数的大小,由比较两个数的大小实现
    def my_max(x, y):
        if x>y:
            return x
        return y
    
    def my_max4(a, b, c, d):
        res1 = my_max(a, b)
        res2 = my_max(res1, c)
        res3 = my_max(res2, d)
        return res3
    print(my_max4(2, 10, 4, 6))
    # 输出
    10
    

      

    五、函数的嵌套定义

    def outer():
        x = 1
        print("outer")
        def inner():
            print("inner")
        print(inner)
        return inner
    res = outer()
    print(res)
    res()
    # 输出
    outer
    <function outer.<locals>.inner at 0x02E936F0>
    <function outer.<locals>.inner at 0x02E936F0>
    inner
    
    """
    函数内定义函数应用场景
    写一个函数
    该函数用户可以通过传参的不同控制函数执行不同的功能
    """
    

      

    六、名称空间

    1、名称空间是什么?

      存放变量名与变量值的内存地址的绑定关系的地方,要想访问一个变量,必须先去名称空间中拿到对应的名字,才能够访问变量的值

    name = "jason"
    print(name)
    print(id(name))
    # 输出
    jason
    49923104
    

    2、名称空间的分类

      ①、内置名称空间:Python解释器提前给你定义好的名字(已经存放到内置名称空间中了)

      len、max、min

      ②、全局名称空间:文件级别的代码

    x = 1
    
    if 1 ==1:
        y = 2
    
    while True:
        z = 3
        break
    
    print(x, y, z)
    # 输出
    1 2 3
    
    # if for while无论嵌套多少层,它们内部所创建的名字都属于全局名称空间
    

      ③、局部名称空间:函数体内创建的名字都属于局部名称空间

    3、名称空间的生命周期

    内置名称空间:只要Python解释器一启动立马创建,关闭Python解释器时自动销毁

    全局名称空间:只要你运行Python文件就会自动创建,程序运行结束时自动销毁

    局部名称空间:函数被调用的时候自动创建,函数执行结束立即销毁(动态创建动态销毁)

    4、名称空间的查找顺序

      ①、首先确定你当前在哪

        站在全局:全局 >> 内置

        站在局部:局部 >> 全局 >> 内置

      ②、函数在定义阶段查找名字的顺序就已经固定了,不会因为函数的调用位置变化而变化

    5、名称空间的作用域

    ①、作用域

      全局作用域(全局有效):内置名称空间 全局名称空间

      局部作用域(局部有效):局部名称空间

    ②、在局部修改全局变量的值

      如果是可变类型,如列表、字典等,可以直接修改,不论嵌套层数

      如果是不可变类型,如字符串等,不可以直接修改,必须使用global加变量名,将这个变量申明为全局变量,才可以修改,修改多个用逗号隔开

    ③、在局部修改局部变量的值(嵌套函数的内层修改外层的变量)

      如果是可变类型,如列表、字典等,可以直接修改,不论嵌套层数

      如果是不可变类型,如字符串等,不可以直接修改,必须使用nonlocal加变量名,将这个变量申明为非局部变量,才可以修改,修改多个用逗号隔开

  • 相关阅读:
    iframe页面调用父窗口JS函数
    href超级链接里加上javascript代码的,还有target问题
    IE上的兼容性调整问题烦死啦
    如何在java web工程下建立存储property文件的文件夹,让Java程序直接读取
    当是class com.cosl.po.Pc$$EnhancerByCGLIB$$38c58f03时,反射属性都他妈不好用了
    好奇怪啊,如果邮箱JSON格式的字符串不是在一行上,那么转为JSON将转换不成功,估计是数据格式有问题吧
    flexpaper上传带中文名字的文档,在页面显示若出现404错误时,请在server.xml文件中进行编码utf-8
    loger4j时间一长,就不向数据库里写日志啦,然而重新启动工程后就可以再次向数据库写日志,好奇怪
    直接在filter过滤器代码里加org.apache.struts2.ServletActionContext.getRequest()会出现空指针情况
    ssh框架从页面传中文发生乱码时怎么解决,就是添加一个字符编码拦截器。用springframework自带的便可
  • 原文地址:https://www.cnblogs.com/DcentMan/p/11164904.html
Copyright © 2020-2023  润新知