zoukankan      html  css  js  c++  java
  • python之闭包、装饰器、生成器、反射

    1. 函数的作用域

      1.在函数定义时候就固定,与调用位置无关,在调用的时候返回到函数定义的位置

    x=1 #全局作用
    def f1():      #整个f1函数是定义阶段
        def f2():
            print(x)
        return f2
    
    
    def foo(func):
        x=3
        func() #func()调用阶段
    x=200  #这样定义x又变成全局了
    foo(f1())          #执行foo(f1()) 返回到F1函数里找x所以打印是1不是3

    生成器

    2.名称空间

    内置名称空间:在python解释器启动产生的空间,简单理解就是python自带的方法比如:max()len()

    全局名称空间 :在全局定义的好的名称空间,文件级别的产生的 比如:

    x=1  #全局作用
    def test():
      x=2 #局部作用
    print(x) test()

    if x=1 y=2
    #全局作用
    #在执行test()调用的时候先加载内置查找有没有test这个内置函数,如果去全局里查找test这个函数方法,最后局部
    
    

    局部名称空间:在调用函数时候产生局部名称空间 y=2,在调用teset()立马产生了局部作用空间

    nonlocal x 函数正上方的x的变量
    global x 改成全局的变量

    3.闭包函数

    闭包函数的作用主要在与装饰器

    函数式编程里面闭包只是给函数捆绑死一个值或者状态

    1.定义在函数内部的函数

    2. 包含对外部作用域名字的引用,而不是对全局作用域名字的引用

    3.该内部函数就称为闭包函数

    import requests
    #第一种传参闭包
    def re(func):
        def get():
            return requests.get(func).text
        return get
    
    baidu=re('http://www.baidu.com')
    baidu1=re('http://www.souhu.com')
    print(baidu())
    
    #第二种自定义固定值闭包函数
    def test():
        url='http://www.baidu.com'
        def gett():               #gett()是闭合函数外面包裹这个url
            return requests.get(url).text
        return gett
    func=test()
    print(func())


    def ff():
      url=‘nq.com’
      func() #此时的func已经一种状态就是url这个百度地址不会
    ff() #得到的结果是url='http://www.baidu.com'


    4.装饰器

    装饰器的定义:1.在不变动主功能函数的前提下,为其添加上新的功能或者状态。

    例:比如抓数据时候,我们需要添加计时器,显示抓取用了多少时间,

    写一个te函数是计时器功能,这样可以给爬取baidu、搜狐网站添加上这个计时器。

    第一种装饰器写法,其实是给闭包函数添加了一个功能

    import requests
    improt time
    #第一种传参闭包,这里当主功能函数
    def re(func):
        def get():
            return requests.get(func).text
        return get
    
    baidu=re('http://www.baidu.com')
    baidu1=re('http://www.souhu.com')
    print(baidu())
    
    
    #装饰器,给获取百度数据添的用时
    def te(func):
        def timer():
            start=time.time()
            func()
            stop=time.time()
            print("获取数据的时间%s"%(stop-start))
        return timer
    
    baidu=te(baidu)
    baidu()

     第二种写法

    这种方法适合用@装饰器函数名称,上面例子是闭包函数,已经闭包了是不可以种@的来装饰建议使用  函数调用方式

    n是表示给传参的函数,以防万一最要用*args,**kwargs的方式

     1 import psutil
     2 def count(func):
     3     def timer():
     4         fu=psutil.cpu_count()
     5         print(fu)
     6         func(1)
     7     return timer
     8 
     9 
    10 #查看cpu使用情况的一个函数
    11 @count
    12 def main(n):
    13     res=psutil.cpu_times()
    14     print(res)
    15     print(n)
    16 
    17 #查看Process的一个函数n
    18 @count
    19 def test(t):
    20     fl=psutil.Process
    21     print(fl)
    22     print(t)
    23 
    24 
    25 test()
    26 main()
    View Code

    装饰器的细节问题:

    from functools import wraps 在装饰器中添加显示备注信息,如下代码
    import psutil
    from functools import wraps
    def count(func):
        @wraps(func)    #这里需要添加wraps这个装饰器
        def timer():
            fu=psutil.cpu_count()
            print(fu)
            func(1)
        return timer
    
    
    #查看cpu使用情况的一个函数
    @count
    def main(n):
        '''
        这个是mian函数的
    
        '''
        res=psutil.cpu_times()
        print(res)
        print(n)
    #return 123 如果函数里有return 打印这个函数结果时候显示空 因为,main显示已经被conunt函数装饰了,所以要在timer里面retrun才对
    print(main.__doc__) #这里是打印上面的备注信息

     生成器

    生成器:不断调用和返回值,生成器

    迭代器:可以被next()函数调用并不断返回下一个值的对象称为迭代器,可以直接作用于for循环的对象统称为可迭代对象

    # def Pycharm(name):
    #     food_list = []
    #     food = yield food_list
    #     print("%s想吃%s" % (name, food))
    #     food_list.append(food)
    #     print(food_list)
    #
    #
    # res = Pycharm('alex')
    # next(res)   #next 会停留在 food=yield这里,send传送后继续执行下面的内容
    # res.send('fangfood')

     python之反射

    反射即想到4个内置函数分别为:getattr、hasattr、setattr、delattr  获取成员、检查成员、设置成员、删除成员下面逐一介绍先看例子

    它的核心本质其实就是利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动

    class func():
    
        def __init__(self):
            self.teacher='teacher'
            self.student='student'
            self.age='ee'
            self.name='name'
    
    
        def test01(self):
            print('反射机智显示test01功能%s' %self.teacher)
    
    
        def test02(self):
            print('反射机智显示test02功能%s' %self.student)
    
    func=func()
    
    def run():
        '''
    
        :return:通过res用户输入相对应的变量、函数方法
        通过反射机制来判断、增删添改
        '''
        res=input('>>我想执行里面的函数:').strip()
        hasa=hasattr(func,res)         #hasattr 可以判断func类中是否存在res传入的变量或者函数方法
        res=getattr(func,res,'not find') #getattr 可以获取传入方法或者函数的执行结果,
                                        # 得到是内存地址需要通过res()来展示内容
                                        #not find意思 如果没有找到相对应的变量和函数 通过print(res())来打印出notfind
    
        # print(res())
        tom=setattr(func,res,18)      #setattr 可以修改传入变量的结果 比如self age=17 通过setattr可以修改成18
        print(func.age)
        delattr(func,'age')           #delattr 删除age这个变量
        print(func.age)
    
        # setattr(func,res,18)
    run()
  • 相关阅读:
    php静态调用非静态方法
    phalcon 框架3.0更新时报错
    centos7.5更换docker-ce镜像源
    腾讯云更换镜像源遇到的坑
    php cli模式下调试
    审查php.ini自动分析程序
    docker WARNING: IPv4 forwarding is disabled. Networking will not work.
    git常用命令,制作缩写命令
    学习GRPC(一) 简单实现
    mac与linux服务器之间使用ssh互通有无
  • 原文地址:https://www.cnblogs.com/yingfei/p/9762656.html
Copyright © 2011-2022 走看看