iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >python之yield与装饰器
  • 380
分享到

python之yield与装饰器

pythonyield 2023-01-31 07:01:18 380人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

防伪码:忘情公子著python中的yield:  在之前发布的《Python之列表解析与生成器》中我们有提到过,生成器所实现的是跟列表解析近似的效果,但是我们不能对生成器做一些属于列表解析的操作。  因为生成器本身就不是一个列表,它只是模拟

防伪码:忘情公子著


python中的yield:

  在之前发布的《Python之列表解析与生成器》中我们有提到过,生成器所实现的是跟列表解析近似的效果,但是我们不能对生成器做一些属于列表解析的操作

  因为生成器本身就不是一个列表,它只是模拟了一个类似列表的行为,因此,施加在列表中的很多操作,对生成器而言是无效的。

  由于生成器表达式并不会直接创建出序列形式的列表,因此不能对其进行索引、切片,不能执行任何常规的列表操作。比如:弹出元素(pop())、添加元素(append())等等。但是我们可以通过list函数将生成器转换成列表。

In [1]: list((i**2 for i in range(1,11)))
Out[1]: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

  很多情况下我们需要生成更为复杂的结果,又不想基于某个列表来实现,但是简单的使用一个生成器表达式很难实现此种行为。此时我们可以通过一个自定义函数来完全实现类似的效果。  

In [2]: def genNum(x):
   ...:     y = 0
   ...:     while y <= x:
   ...:         yield y
   ...:         y += 1
   ...: 

In [3]: g1 = genNum(10)

In [4]: type(g1)
Out[4]: generator

In [5]: g1.next()
Out[5]: 0

In [6]: g1.next()
Out[6]: 1

In [7]: g1.next()
Out[7]: 2

In [8]: g1.next()
Out[8]: 3

In [9]: g1.next()
Out[9]: 4

In [10]: g1.next()
Out[10]: 5

In [11]: g1.next()
Out[11]: 6

In [12]: g1.next()
Out[12]: 7

In [13]: g1.next()
Out[13]: 8

In [14]: g1.next()
Out[14]: 9

In [15]: g1.next()
Out[15]: 10

In [16]: g1.next()
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-16-9066a8f18086> in <module>()
----> 1 g1.next()

StopIteration:

  yield本身并不是一个返回值,却能够生成一个生成器对象。

  yield保存着一个对象的状态信息。(快照的例子:快照当中保存的是执行快照时的状态)

  如上例所看到的,当我们在函数中使用yield,会返回一个生成器对象。

  求1到20以内所有正整数的平方:

In [17]: def genNum(n):
    ...:     count = 1
    ...:     while count <= n:
    ...:         yield count ** 2
    ...:         count += 1
    ...: 

In [18]: g1 = genNum(20)

In [19]: for i in g1:
    ...:     print i
    ...: 
1
4
9
16
25
36
49
64
81
100
121
144
169
196
225
256
289
324
361
400


Python中的装饰器:

  装饰器定义:

    本质上是一个函数

    功能是用来装饰其他函数。就是为其他函数添加附加功能

  装饰器=高阶函数+嵌套函数

  装饰器特定的原则:

    不能修改被装饰的函数的源代码(线上环境)

    不能修改被装饰的函数的调用方式

    不能修改被装饰的函数的返回值

  装饰器可以抽离出大量的函数中与函数无关的功能,把函数本身只作为一个核心,在必要时如果函数的核心功能不够,就用装饰器装饰一下本次调用所需要的功能,于是运行结束了,下次当需要其它功能时再用装饰器给重新装饰一下就可以了,这就是装饰器。

  装饰器需要接受一个函数对象作为其参数,而后对此函数做包装,以对此函数进行增强。


  实现装饰器的知识储备:

    1、函数即“变量“(说明变量在内存中存在的方式)

    2、高阶函数

    a.把一个函数名当做实参传给另一个函数(可以实现在不修改被装饰函数源代码的情况下为其添加功能)

import time
def bar():
    time.sleep(3)
    print('in the bar')
def test1(func):
    start_time = time.time()
    func()
    stop_time = time.time()
    print('The func run time is %s'% (stop_time-start_time))
test1(bar)

    b.返回值中包含函数名(可以实现不修改被装饰函数的调用方式)

import time
def bar():
    time.sleep(3)
    print('in the bar')
def test2(func):
    print(func)
    return func
x = test2(bar)    #此处也可以改成:bar = test2(bar)
bar()

  当用bar = test2(bar)时,此处定义的bar变量名就会覆盖之前定义bar函数时生成的变量名bar。

  如此的话,那之前定义的bar函数进行调用时就是使用新定义的bar变量名引用其在内存中的位置,从而达到不修改bar函数调用方式的目的。

    3、嵌套函数

import time
def foo():
    print('in the foo')
def bar():
    print('in the bar')
bar()
foo()

  不带参数的func(被装饰的函数):

In [20]: def decorative(func):
    ...:     def wrapper():    #定义一个包装器
    ...:         print "Please say something: "
    ...:         func()    #调用func,这个func是我们自己定义的
    ...:         print "No zuo no die..."
    ...:     return wrapper
    ...:

In [21]: @decorative    #使用@符号调用装饰器
    ...: def show():    #定义func,名字取什么都无所谓,它只是用来传给装饰器中的func参数
    ...:     print "I'm from Mars."
    ...: show()
    ...:
Please say something:
I'm from Mars.
No zuo no die...

  如上例所示,show函数本身只有一个print语句,而使用装饰器以后,就变成了三个print,这里的print可以改成任何其它的语句,这就是函数的装饰器。

  带参数的func(被装饰的函数):

In [22]: def decorative(func):
    ...:     def wrapper(x):
    ...:         print "Please say something...>"
    ...:         func(x)
    ...:         print "no zuo no die..."
    ...:     return wrapper
    ...:

In [23]: @decorative
    ...: def show(x):
    ...:     print x
    ...: 

In [24]: show("hello,mars.")
Please say something...>
hello,mars.
no zuo no die...

  现在我们来写一个简单的为函数添加执行时间的装饰器函数:

import time
def timmer(func):
    def wrapper(*args,**kwargs):
        start_time = time.time()
        a = func()
        stop_time = time.time()
        print('The func run time is %s'% (stop_time-start_time))
        return a
    return wrapper
@timmer
def foo():
    time.sleep(3)
    print('in the foo')
print(foo())

  接下来再写一个现实生活中能用得到的:

  需求如下:

   假定有三个页面,现在要实现其中2个页面验证登录之后才能访问,另一个页面不用验证即可访问

  首先定义三个页面函数:

def index():
    print('Welcome to index page')
    return 'from index page'
def home():
    print('Welcome to home page')
    return 'from home page'
def bbs():
    print('Welcome to bbs page')
    return 'from bbs page'

  然后定义装饰器函数:

user = sean
passwd = abc123
def auth(auth_type='local'):
    def out_wrapper(func):
        def wrapper(*args,**kwargs):
            if auth_type == 'local':
                username == input('Username: ').strip()
                passWord == input('Password: ').strip()
                if user == username and passwd == password:
                    print('authentication passed')
                    func()
            elif auth_type == 'ldap':
                print('This is ldap authentication')
                func()
        return wrapper
    return out_wrapper

  接下来将装饰器分别应用于home函数与bbs函数:

def index():
    print('Welcome to index page')
    return 'from index page'
@auth(auth_type='local')
def home():
    print('Welcome to home page')
    return 'from home page'
@auth(auth_type='ldap')
def bbs():
    print('Welcome to bbs page')
    return 'from bbs page'

#调用函数   
index()
home()
bbs()

--结束END--

本文标题: python之yield与装饰器

本文链接: https://www.lsjlt.com/news/190786.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • python之yield与装饰器
    防伪码:忘情公子著python中的yield:  在之前发布的《python之列表解析与生成器》中我们有提到过,生成器所实现的是跟列表解析近似的效果,但是我们不能对生成器做一些属于列表解析的操作。  因为生成器本身就不是一个列表,它只是模拟...
    99+
    2023-01-31
    python yield
  • Python学习之装饰器与类的装饰器详解
    目录装饰器装饰器的定义装饰器的用法类中的装饰器类的装饰器 - classmethod类的装饰器 - staticmethod类的装饰器 - property通过学习装饰器可以让我们更...
    99+
    2024-04-02
  • Python之装饰器
    在Python中一切皆对象,函数是一等对象。这意味着可以通过名字引用函数。>>> a=123 >>> a 123 >>> name='zeng' >>> name 'z...
    99+
    2023-01-31
    Python
  • day20-python之装饰器
    1.装饰器 1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 import time 4 def cal(l): 5 start_time=time.time() ...
    99+
    2023-01-31
    python
  • Python装饰器-闭包与函数装饰器
    一、闭包在学习装饰器前,需要先了解闭包的概念。形成闭包的要点:函数嵌套将内部函数作为外部函数的返回值内部函数必须要使用到外部函数的变量下面以一个计算列表平均值的案例来讲解闭包:def make_average(): # 创建一个列表,用来保...
    99+
    2023-05-14
    Python 函数 装饰器
  • Python 语法之装饰器
      装饰器的概念  装饰器是 Python 的一个重要部分。简单地说:就是用于拓展原来函数功能的一种函数,目的是在不改变原函数名(或类名)的情况下,给函数增加新的功能。  这个函数的特殊之处在于它的返回值也是一个函数,这个函数是内嵌 “原”...
    99+
    2023-06-02
  • python进阶之装饰器
    一.无参装饰器 问题:如何计算一段程序的运行时间? 先看一段简单代码: 1 import time 2 def func(): 3 start = time.time() # 记录程序开始时间 4 time.sleep(...
    99+
    2023-01-30
    进阶 python
  • python之装饰器(函数)
    1. 装饰器   遵循的原则:     开闭原则:   对功能的扩展开放  对代码的修改是封闭 # 通用装饰器写法 # 存在的意义: 在不破坏原有函数和原有函数调用的基础上,给函数添加新的功能. def wrapper...
    99+
    2023-01-30
    函数 python
  • Python装饰器与类的装饰器怎么实现
    这篇“Python装饰器与类的装饰器怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Python装饰器与类的装饰器怎么...
    99+
    2023-06-29
  • Python之yield生成器
    1、对比range和xrange的区别:>>> print range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> print xrange(10) xrange(10)...
    99+
    2023-01-31
    生成器 Python yield
  • Python 3 之 装饰器详解
    ------------ 装饰器 -----------------------------------------------------什么是装饰器装饰器是为函数和类指定管理代码的一种方式。装饰器本身的形式是处理其他的可调用对象的可调用...
    99+
    2023-01-31
    详解 Python
  • python学习系列之python装饰器
    一、常规的装饰器,比如 @auth,执行2步操作:1、执行auth函数,并传参func进来2、获取返回值,并赋值给被装饰器的函数的函数名(如让fetch_server_list等于返回值)二、而带参数的装饰器,比如 @auth(before...
    99+
    2023-01-31
    系列之 python
  • Python全栈开发之---装饰器
    1、装饰器的形成过程 1 import time 2 3 def func1(): 4 print('in func1') 5 6 def timer(func): 7 def inner(): 8...
    99+
    2023-01-30
    Python
  • python魔术方法之装饰器
    三个魔术方法:__get__()__set__()__delete__()object.__get__(self,实例名,owner)    #owner = 属主 ,instance = 属主类owner的实例object.__set__...
    99+
    2023-01-31
    魔术 方法 python
  • python装饰器2:类装饰器
    装饰器1:函数装饰器 装饰器2:类装饰器 装饰器3:进阶 本文是装饰器相关内容的第二篇,关于类装饰器。 "类装饰器"有两种解读方式:用来装饰类的装饰器;类作为装饰器装饰其它东西。你如何认为取决于你,两种说法都有出现在其它的文章中。我的...
    99+
    2023-01-30
    python
  • python基础之装饰器详解
    目录一、前言二、高阶函数三、函数嵌套四、装饰器4.1 被装饰方法带返回值4.2 被装饰方法带参数4.3 验证功能装饰器4.4 验证功能装饰器——带参数一、前言 装...
    99+
    2024-04-02
  • python三大器之装饰器详解
    目录装饰器总结装饰器 讲装饰器之前要先了解两个概念: 对象引用 :对象名仅仅只是个绑定内存地址的变量 def func(): # 函数名仅仅只是个绑定内存地址的...
    99+
    2024-04-02
  • Python语法详解之decorator装饰器
    python 是一门优雅的语言,有些使用方法就像魔法一样。装饰器(decorator)就是一种化腐朽性为神奇的技巧。最近一直都在使用 Tornado 框架,一直还是念念不忘 Flas...
    99+
    2024-04-02
  • python之我对装饰器的理解
      从一开始学习python的时候,就一直不是很理解装饰器是个什么东东,再看了很多篇博文和自己动手敲了好多代码后,算是略有了解。  我理解的装饰器是: 在不改变原有函数调用的情况下,对其进行包装,使其变成另外一种函数来使用,一般的用途是 插...
    99+
    2023-01-31
    我对 python
  • python装饰器
    什么是装饰器:   装饰器就是python中的一个语法糖。作用就是在不改动之前代码的情况下给某个函数增加相应想要增加的功能。 假设需求:   我在几个函数内分别放了一部电影,代码如下: 1 def mv1(): 2 print(...
    99+
    2023-01-30
    python
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作