zoukankan      html  css  js  c++  java
  • day_04、函数

    python代码运行原理

      从python开始执行以后,就在内存里开辟一个空间,每当遇到一个变量的时候,就把变量名和值之间的对应关系记录下来。当遇到函数定义的时候,解释器只是象征性的将函数名读到内存,表示知道这个函数存在了。至于函数内部的变量和逻辑,解释器不关心。

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

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

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

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

    命名空间和作用域

    命名空间一共分为三种:

    全局命名空间

    局部命名空间

    内置命名空间

    内置命名空间中存放了python解释器为我们提供的名字:input,print,list...

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

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

    取值顺序

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

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

    作用域

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

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

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

    globals()和locals()

    1 print(globals())
    2 print(locals())
    在全局调用globals和locals
    1 def func():
    2     a = 12
    3     b = 20
    4     print(locals())
    5     print(globals())
    6 
    7 func()
    在局部调用locals和globals

    global关键字,nonlocal关键字。

    global:

      1、声明一个全局变量。

      2、在局部作用域(函数内部)想要对全局变量进行修改时,需要用到global(限于字符串,数字。即全局作用域的列表和字典、集合可以在函数内部直接修改。)

    def func():
        global a
        a = 3
    func()
    print(a)
    
    
    count = 1
    def search():
        global count
        count = 2
    search()
    print(count)
    

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

    li = [1,2,3]
    dic = {'a':'b'}
    
    def change():
        li.append('a')
        dic['q'] = 'g'
        print(dic)
        print(li)
    change()
    print(li)
    print(dic)
    

    nonlocal:

       1、不能修改全局变量

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

    def add_b():
        b = 42
        def do_global():
            b = 10
            print(b)
            def dd_nonlocal():
                nonlocal b
                b = b + 20
                print(b)
            dd_nonlocal()
            print(b)
        do_global()
        print(b)
    add_b()

    函数的嵌套和作用域链

    函数的嵌套调用

    def max2(x,y):
        m  = x if x>y else y
        return m
    
    def max4(a,b,c,d):
        res1 = max2(a,b)
        res2 = max2(res1,c)
        res3 = max2(res2,d)
        return res3
    
    # max4(23,-7,31,11)
    

      函数的嵌套定义

     1 def f1():
     2     print("in f1")
     3     def f2():
     4         print("in f2")
     5 
     6     f2()
     7 f1()
     8 ###########
     9 def f1():
    10     def f2():
    11         def f3():
    12             print("in f3")
    13         print("in f2")
    14         f3()
    15     print("in f1")
    16     f2()
    17     
    18 f1()
    函数的嵌套定义

    函数的作用域链:小范围作用域可以使用大范围的变量,但是反之不行,他是单向的。

     1 def f1():
     2     a = 1
     3     def f2():
     4         def f3():
     5             print(a)
     6         f3()
     7     f2()
     8 
     9 f1()
    10 ################
    11 def f1():
    12     a = 1
    13     def f2():
    14         a = 2
    15     f2()
    16     print('a in f1 : ',a)
    17 
    18 f1()
    函数的作用域链:小范围作用域可以使用大范围的变量,但是反之不行,他是单向的。

    函数名的本质

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

    1、可以被引用

    def fun():
        print('in fun')
    
    print(fun)
    

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

    def f1():
        print('f1')
    
    
    def f2():
        print('f2')
    
    
    def f3():
        print('f3')
    
    l = [f1,f2,f3]
    d = {'f1':f1,'f2':f2,'f3':f3}
    #调用
    l[0]()
    d['f2']()
    

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

    def f1():
        print('f1')
    
    def func1(argv):
        argv()
        return argv
    
    f = func1(f1)
    f()
    

    第一类对象:

    1、可以在运行时创建

    2、可用作函数参数或返回值

    3、可存入变量的实体。

    闭包

    def fun():
        name = 'root'
        def inner():
            print(name)
        return inner()
    fun()
    

     

    def fun():
        name = 'root'
        def inner():
            print(name)
    fun()
    

    闭包函数:

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

    # 函数内部定义的函数称为内部函数

    由于有了作用域的关系,我们就不能拿到函数内部的变量和函数了。如果我们想拿就要返回。

    我们都知道函数内的变量我们想在函数外部用,可以直接返回这个变量。

    那么我们想在函数的外部直接调用函数内部的函数。直接返回这个函数的名字。(即fun,不带‘()’)

    def fun():
        name = 'root'
        def inner():
            print(name)
        return inner
    
    fun()()
    

    判断闭包函数的方法

    def fun():
        name = 'root'
        def inner():
            print(name)
        print(inner.__closure__)
        return inner
    
    fun()()
    

     #(<cell at 0x02DF6F10: str object at 0x0506C8E0>,)

    name = 'ubuntu'
    def fun():
        # name = 'root'
        def inner():
            print(name)
        print(inner.__closure__)
        return inner
    
    fun()()
    

      闭包嵌套

     1 def wrapper():
     2     money = 100
     3     def fun():
     4         name = 'root'
     5         def inner():
     6             print(name, money)
     7         return inner
     8     return fun
     9 
    10 wrapper()()()

    装饰器

    装饰器本质上就是一个python函数,它可以在其他函数不需要做任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象。装饰器的应用场景:插入日志,性能测试,事物处理,缓存等。

    开放封闭原则

    1、对扩展是开放的

      任何一个程序,不可能在设计之处就已经想好了所有的功能,并且不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。

    2、对修改是封闭的

      已经上线的函数,对其进行修改,很可能会影响其他已经在使用该函数的用户。

    装饰器模板

    def timer(func):
        def inner(*args,**kwargs):
            '''执行函数之前要做的'''
            re = func(*args,**kwargs)
            '''执行函数之后要做的'''
            return re
        return inner
    

    带参数的装饰器    #待填

    def outer(flag):
        def time(fun):
            def fun(*args, **kwargs):
                if flag:
                    pass
                ret = fun(*args, **kwargs)
                if flag:
                    pass
                return ret
            return fun
        return time
    
    @outer(False)
    def func():
        pass  

    多个装饰器装饰一个函数---俄罗斯套娃

    def wrapper1(func):
        def inner():
            print('wrapper1 ,before func')
            func()
            print('wrapper1 ,after func')
        return inner
    
    def wrapper2(func):
        def inner():
            print('wrapper2 ,before func')
            func()
            print('wrapper2 ,after func')
        return inner
    
    @wrapper2
    @wrapper1
    def f():
        print('in f')
    
    f()
    

     参数的用法

    def fun(start, stop=None, step=1):
        if stop is None:
            start, stop = 0, start
        result = []
        i = start
        while i < stop:
            result.append(i)
            i += step
        return result
    
    print(fun(10))
    

     函数的有用信息

    from functools import wraps
    
    def logger(f):
        @wraps(f)
        def inner(*args, **kwargs):
            """
            :param args: 函数名,密码
            :param kwargs: 备用
            :return:  True
            """
            ret = f(*args, **kwargs)
            return ret
        return inner
    
    @logger
    def login(username,password):
        """
        此函数是完成登录功能的函数,需要用户名,和密码两个参数,返回True 登陆成功
        :return:  True
        """
        print(666)
        return True
    # login(1,2)  #inner()
    # # login('alex', 123)
    print(login.__doc__)
    print(login.__name__)
    

      

     

     

  • 相关阅读:
    使用PowerDesigner对NAME和COMMENT互相转换
    HIMSS EMRAM新版标准将于2018年1月1日生效
    [转]Scrapy简单入门及实例讲解
    转:Oracle 执行计划(Explain Plan) 说明
    mac 安全控制 允许安装任何来源的包
    [转]Python中出错:ImportError: No module named win32com.client
    Windows环境下安装配置Mosquitto服务及入门操作介绍
    Mosquitto--webServer应用测试结果
    Paho -物联网 MQTT C Cient的实现和详解
    mosquitto设置用户名和密码
  • 原文地址:https://www.cnblogs.com/kongzhou/p/9101880.html
Copyright © 2011-2022 走看看