zoukankan      html  css  js  c++  java
  • 函数对象与函数嵌套

    函数对象:

      函数对象指的是函数可以被当作数据来处理,具体分为四个方面的使用:

    1.函数的引用

    def index():
        print('fuck')
    
    
    a = index
    a()

    2.函数可以当作参数传递

    def add(x,y):
        return x + y
    def foo(x,y,add):
        return add(x,y)
    
    
    foo(1,2,add)
    print(foo(1,2,add))

    3.函数的返回值可以是一个函数

    def bar():
        return add
    
    
    func = bar()
    func(2,3)
    print(func(2,3))

    4.函数名可以当作容器类型的元素

    def index():
        print('fuck')
    
    
    l1 = [1,2,index,index()]
    f = l1[2]

    函数的嵌套

      在函数内调用函数

    def index():
        print('hello')
    def func():
        index()
        print('nmh')
        
    
    func()
    >>>hello
       nmh
    def index():
        def home():
            print('hello')
        home()
    
    
    index()
    >>hello

    比较大小

    def func1(x,y):
        if x>y:
            return x
        else:
            return y
    def func2(a,b,c,d):
        result = func1(a,b)
        result = func1(result,c)
        result = func1(result,d)
        return result
    
    
    print(func2(123,321,53,1))
    >>321

    名称空间:

      存放名字的空间,如变量名,函数名

      在程序执行期间最多会存在三种名称空间:

        1.内置名称空间:python解释器提前定义完的名字,在解释器开启时生效,关闭时回收

        2.全局名称空间:存放于文件级别的名字,启动py文件时生效,当前页面代码执行结束后失效

           if,while,for内部定义的名字执行之后都存放于全局名称空间。

        3.局部名称空间:函数内部定义的名字,当调用当前函数时生效,函数体代码执行结束失效

    x = 10   # 全局名称空间
    
    def f1():
        x = 20   # 局部名称空间
        
        def f2():
            print('from f1',x)
        f2()
        
    f1()
            
    print('from file.py',x)   

      名称空间的查找顺序:

        局部:局部 ===》全局===》内置

        全局:全局 ===》内置  #内置找不到,报错

        函数内部使用的名字,在定义阶段已经定死了,与你的调用位置无关

    x = 1
    def inner():
        x = 2
        def wrapper():
            print(x)  #在局部找x
        wrapper()
    x = 111
    inner()   #结果为2
    print(x) #在全局查找,结果为111

    练习

    x = 1
    def index(arg = x):
        print(x)
        print(arg)
    
    x = 2
    index()
    >>2
      1

    作用域:

      分类:1.全局作用域:位于全局名称空间、内置名称空间中的名字属于全局范围,该范围内的名字全局存活(除非删除)、全局有效(任何位置可用);

         2.局部作用域:位于局部名称空间中的名字属于局部范围。该范围内的名字临时存活(在函数调用时临时生成,结束后释放)、局部有效(只能在函数内使用)。

    名字查找的优先级: 在全局作用域查找名字时,起始位置是全局作用域,先查全面名称空间,再找内置名称空间,都没有会抛出异常。

              在局部作用域查找名字时,起始位置时局部作用域,先查找局部名称空间,再去全局作用域查找:全局名称空间》》内置名称空间, 都找不到会抛出异常。

    在内嵌的函数查找名字时,会优先查找自己局部作用域的名字,然后由内而外一层层查找外部嵌套函数定义的作用域,没有找到,则查找全局作用域

    x = 1
    def outer():
        x = 2
        def inner():
            x =3
            print('inner x:%s' %x)
        inner()
        print('outer x:%s' %x)
    outer()
    结果为:inner x:3
          outer x:2

    在函数内,无论嵌套多少层,都可以看到全局作用域的名字,若要在函数内修改全局名称空间中名字的值,当值为不可变类型时,需要用到global

    global

    x = 1
    def foo():
        global x #声明x为全局变量
        x = 2
    foo()
    print(x)
    >>2

    当实参的值为可变类型时,函数体内对该值的修改会直接反应到原值

    l1 = [1,2,3]
    def index(a):
        l1.append(a)
        print(l1)
    index(5)
    >>[1,2,3,5]

    对于嵌套多层的函数,使用nonlocal可以将名字声明为来自外部嵌套函数定义的作用域(非全局)

    def f1():
        x = 2
        def f2():
            nonlocal x
            x = 3
        f2() #调用f2(),修改f1作用域中名字x的值
        print(x) # 在f1作用域查看x
    
    
    f1()
    >>3

    nonlocal x会从当前函数的外层函数开始一层层去查找名字x,若是一直到最外层都找不到,则会抛出异常。

  • 相关阅读:
    ASP.NET MVC2 第四章Ⅱ
    关于Windows 7硬盘安装方法大全
    新手看Lambda
    ASP.NET MVC2 第五章Ⅲ
    守护线程
    双鱼
    信号量与互斥锁
    public,private,protected访问权限在Java,C++中的解析
    final in java
    Java code standard
  • 原文地址:https://www.cnblogs.com/littleb/p/11835368.html
Copyright © 2011-2022 走看看