zoukankan      html  css  js  c++  java
  • Python函数初识二

    一、命名空间的概念

    我们首先回忆一下Python代码运行的时候遇到函数是怎么做的,从Python解释器开始执行之后,就在内存中开辟里一个空间,每当遇到一个变量的时候,就把变量名和值之间对应的关系记录下来,但是当遇到函数定义的时候,解释器只是象征性的将函数名读如内存,表示知道这个函数存在了,至于函数内部的变量和逻辑,解释器根本不关心。

      等执行到函数调用的时候,Python解释器会再开辟一块内存来储存这个函数里面的内容,这个时候,才关注函数里面有哪些变量,而函数中的变量回储存在新开辟出来的内存中,函数中的变量只能在函数内部使用,并且会随着函数执行完毕,这块内存中的所有内容也会被清空。

    我们给这个‘存放名字与值的关系’的空间起了一个名字-------命名空间。

    代码在运行伊始,创建的存储“变量名与值的关系”的空间叫做全局命名空间;

    在函数的运行中开辟的临时的空间叫做局部命名空间。

    命名空间一共分为三种:

      全局命名空间:存储变量名与其对应的值得空间

      局部命名空间:函数运行时用到的临时空间,函数结束时会释放。

      内置命名空间:存放Python解释器内置的函数,如print、input、等

    三种命名空间之间的加载与取值顺序:

    加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)

    取值顺序:

      在局部调用:局部命名空间->全局命名空间->内置命名空间

      在全局调用:全局命名空间->内置命名空间

    综上所述,在找寻变量时,从小范围,一层一层到大范围去找寻。

    #举例1
    name = '小明'
    def func():
        name= '小芳'
        print(name)   #小芳
    func()
    #举例2
    def len(a):
        return (a)
    print(len([1,2,3]))   #len是内置参数,取值顺序最后[1, 2, 3] 

    作用域

    作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域。

    全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效

    局部作用域:局部名称空间,只能在局部范围内生效

     globals和locals方法

    globals返回的是当前模块的全局变量

    locals返回的是局部变量,locals返回的是当前所在最小命名空间的局部变量的“拷贝”,返回的变量都是原有变量的拷贝。

    #通过以下代码可比较其区别
    a = 8
    def func():
        a = 5
        print(a)
        print(locals())
        print(globals())
    func()
    print(locals())
    print(globals())
    

      global和nonlocal关键字

    global:

      1,声明一个全局变量。

      2,在局部作用域想要对全局作用域的全局变量进行修改时,需要用到 global(限于字符串,数字)

           ps:对可变数据类型(list,dict,set)可以直接引用不用通过global。

    nonlocal:

      1,不能修改全局变量。

      2,在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改变。

    函数的嵌套

    def f1():
        print("in f1")
        def f2():
            print("in f2")
    
        f2()
    f1()
    ###########
    def f1():
        def f2():
            def f3():
                print("in f3")
            print("in f2")
            f3()
        print("in f1")
        f2()
        
    f1()
    

     函数的名:

    函数名本质上就是函数的内存地址。

    1)、可以被引用,函数名可以赋值给其他变量

    2)、可以被当作容器类型的元素

    3)、可以当作函数的参数和返回值

    def func1():
        print(666)
        return 2
    def func2(y):
        print(222)
        return 8
    ret1 = func2(func1())
    print(ret1) 

    闭包函数内部函数包含对外部作用域而非全剧作用域变量的引用,该内部函数称为闭包函数,函数内部定义的函数称为内部函数

    怎样判断闭包函数:

    在外层函数的内部,执行inner()

    #怎样判断闭包函数:
    def wrapper():
        def inner():
            name = '小明'
            print(name)
        print(inner.__closure__)  # 打印出来的值是None,就不是闭包函数
        inner()
    wrapper()
    

     闭包的用处闭包的用处:如果说你内存函数是个闭包,python内部有一个机制,遇到闭包,他会在内存中开启一个内存空间,不会随着函数的结束而关闭

     闭包爬虫的应用举例:

    from urllib.request import urlopen
    print(urlopen('http://www.cnblogs.com/jin-xin/articles/8259929.html').read())
    def index(url):
        content = urlopen(url).read()
        def get():
            with open('爬虫','a') as f1:
                f1.write(content.decode('utf-8'))
        return get
    index('http://www.cnblogs.com/jin-xin/articles/8259929.html')()
    def index():
        url = "http://www.xiaohua100.cn/index.html"
        def get():
            return urlopen(url).read()
        return get
    

     函数的有用信息:

      1)获取函数的说明信息和函数名(__doc__和__name__

    def f1():
        '''
        本函数的功能:绘图功能,实时接收数据并绘图.
        :return: 绘图需要的数据,返回给前端某标签
        '''
        print(f1.__doc__)
        print(f1.__name__)
        print(666)
    f1()
    函数的说明信息和函数名

      打印结果:

        本函数的功能:绘图功能,实时接收数据并绘图.
        :return: 绘图需要的数据,返回给前端某标签
        
    f1
    666
    打印结果

     2)wraps函数

    from functools import wraps
    def wrapper(func):
        @wraps(func)
        def inner(*args,**kwargs):
            '''执行函数前进行的操作'''
            ret = func(*args,**kwargs)
            '''执行函数后进行的操作'''
            return ret
        return inner
    @wrapper
    def f1():
        '''
        本函数的功能:绘图功能,实时接收数据并绘图.
        :return: 绘图需要的数据,返回给前端某标签
        '''
        print(f1.__doc__)
        print(f1.__name__)
    f1()
    

       引入wraps函数后的打印结果:

    引入wraps函数后的结果

       未引入wraps函数之前的打印结果:

    执行函数前进行的操作
    inner
    未引入wraps函数之前的打印结果

     3)*args和**kwargs:聚合与打散

    def wrapper(func):
        def inner(*args,**kwargs):
            '''执行函数前进行的操作'''
            ret = func(*args,**kwargs)
            '''执行函数后进行的操作'''
            return ret
        return inner
    @wrapper # f1 = wrapper(f1)
    def f1(a,b,c,d):  # 接收函数的时候,* 聚合.
        print(a,b)
        # print(args) # (1,2,3,4)
    f1(1,2,2,3)
    
    f1(*[1,2,3,4])  # 执行函数时,加个*打散
    

      

      

     

     

  • 相关阅读:
    servlet.txt笔记
    用数组实现集合的功能
    用父类声明的变量和用接口声明的变量的区别
    DHTML_____document对象的方法
    DHTML_____window对象的事件
    DHTML_____window对象属性
    DHTML_____window对象方法
    DHTML_____如何编写事件处理程序
    常用点击事件(鼠标、光标、键盘、body)
    鼠标滑动显示不同页面的效果——————获取鼠标相对于整个页面的坐标
  • 原文地址:https://www.cnblogs.com/Ming-Hui/p/8399770.html
Copyright © 2011-2022 走看看