0x00000000030A40D0位置(这个位置应该是指内存位置)存有一个function(方法)叫target;在 target后面加上(),表示调用该方法,即输入target(),“大脑”便按照target方法所写的代 码逐条执行,于是打印出了target字符串,并且“大脑”明白在0x00000000030A4268位置有一 个叫returnme的方法;因为target对象调用后是会返回一个returnme方法,并且方法是可以被调用的,因 此你可以直接这样书写target()(),“大脑”会逐条执行target中的代码,然后return一个 returnme,因为多加了一个(),表示要对返回的returnme进行调用,于是再次逐条执行returnme中的代码 ,最后便能看到15、16的打印结果;而returnme方法是没有返回任何可调用的对象,因此当输入 returnme()()时,“大脑”会报错。

下面我们可以来解释一下脚本2和脚本3的运行详情,之前说过,装饰器的工作原理就是脚本1代码所演 示的那样。

@decorator

def target():

...

等同于

def decorator(target)():

...

注:python语法中以上写法是非法的,以上只是为了便于理解。

当你调用被装饰方法target时,其实首先被执行的是作为装饰器的decorator函数,然后“大脑 ”会把target方法作为参数传进去,于是:

#脚本2

def decorator(func):

func()

print('this is decorator')

@decorator

def target():

print('this is target')

target

-------------------------------------------

实际运行情况:

首先调用decorator方法:decorator()

因为decorator方法含1个参数,因此将target传入:decorator(target)

运行代码“func()”,根据传入的参数,实际执行target(),结果打印出:this is target

运行代码"print('this is decorator')",结果打印出:this is decorator

对比脚本3的运行情况:

#脚本3

def decorator(func):

func()

print('this is decorator')

@decorator

def target():

print('this is target')

target()

-------------------------------------------

实际运行情况:

首先调用decorator方法:decorator()

因为decorator方法含1个参数,因此将target传入:decorator(target)

运行代码“func()”,根据传入的参数,实际执行target(),结果打印出:this is target

运行代码"print('this is decorator')",结果打印出:this is decorator

以上与脚本2中运行情况完全相同,接下来便是执行脚本2中target没有的(),也就是执行调用命令。

由于decorator(target)没有返回一个可以被调用的对象,因此“大脑”提示错

误:'NoneType' object is not callable

如果你还不是很清楚,请看下面的等价关系:

@decorator

def target():

...

等同于

def decorator(target)():

...

因此:

target == decorator(target)

target() == decorator(target)()

所以:

假设有一个变量var=target,在将target赋值给var时,其实是将decorator(target)的调用结果赋值给

var,因为var不具备调用性(not callable),因此执行var()时,编译器会报错它是个NoneType对象,

不能调用。

综上所述,你大概已经能够明白所谓的装饰器是怎么一回事,它是怎么工作的。但脚本2和脚本3中的 写法会带来一些困惑,这个困惑就是通过我们编写的decorator装饰器对target进行装饰后,将target变 成了一个永远不能被调用的方法,或者说变成了一个调用就报错的方法。这跟我们的使用习惯以及对方法 的认识是很不协调的,毕竟我们还是习惯一个方法天生注定可以被调用这种看法。所以为了满足我们对方 法的定义,我们最好将作为装饰器的方法写成一个可以返回具有被调用能力的对象的方法。

#脚本4

def whatever():

print('this is whatever')

def decorator(func):

func()

print('this is decorator')

return whatever  #1

@decorator

def target():

print('this is target')

------------------------------

输入:target

结果:

this is target

this is decorator

输入:target()

结果:

this is target

this is decorator

this is whatever

在#1的位置,你可以return任何可以被调用的方法或类,甚至你可以直接写成:

def whatever():

print('this is whatever')

def decorator(func):

return whatever

python装饰器副作用_对Python 装饰器的理解心得相关推荐

  1. 多层神经元感知器模型_使用多层感知器模型对星系进行分类

    多层神经元感知器模型 Cosmos is an intriguing space to observe and analyse, it is the stronghold for any scienc ...

  2. python中的装饰器、装饰器模式_浅析Python装饰器以及装饰器模式

    漫谈 如果作为一个Python入门,不了解Python装饰器也没什么,但是如果作为一个中级Python开发人员,如果再不对python装饰器熟稔于心的话,那么可能并没有量变积累到质变. 我以前也看过很 ...

  3. python制作音乐模块_用Python打造一个只属于你的专属音乐播放器,享受动手的快乐!...

    平常我们总是用爬虫爬取网页上的音乐,今天我们换个玩法,用Python制作一个独一无二只属于你的音乐播放器,小伙伴们觉得如何?如果觉得提议还不错,那就立即动手吧! 一.需要的库 pygame tkint ...

  4. python编程免费小说_使用Python开发小说下载器,不再为下载小说而发愁

    有点荒废 这几天有点荒废,之前弃坑的网文<伏天氏>,这几天又给捡起来了.然后一发不可收拾的只想看小说,荒废了我的学习.在这里我要检讨啊..... 像我这样的穷人,看小说肯定是找免费的网站, ...

  5. python如何制作脚本_用python给自己做一款小说阅读器过程详解

    前言 前一段时间书荒的时候,在喜马拉雅APP发现一个主播播讲的小说-大王饶命.听起来感觉很好笑,挺有意思的,但是只有前200张是免费的,后面就要收费.一章两毛钱,本来是想要买一下,发现说的进度比较慢而 ...

  6. python文档测试_【Python入门】19.调试器pdb、单元测试unittest和文档测试doctest

    笔记更新于2019年12月4日, 摘要:各种调试方法介绍assert.logging.调试器pdb:单元测试unittest的编写方法.如何运行单元测试:文档测试doctest的编写 写在前面:为了更 ...

  7. python中级项目下载_中级Python复习:教程,项目思想和技巧

    python中级项目下载 本文旨在向Python初学者和开发人员介绍Python中使用的一些关键概念,这些概念一开始就没有讲授. 如果您可以创建二次方根求解器,则可以理解本文. 这些是我一天之内没有学 ...

  8. python需要具备什么_入门Python需要掌握哪些技能呢?

    随着人工智能时代的来临,Python开始崭露头角并迅速吸引了人们的广泛关注.很多人想要从事Python开发,但零基础入门Python,需要了解什么呢?看看你都掌握了吗? 1.Python是如何被解释执 ...

  9. python的知识体系_最新Python知识体系梳理

    课程目录 Day01 Python教程:01.前提概要.wmv Python教程:02.Python基础复习.wmv Python教程:03.Python基础复习.wmv Python教程:04.Py ...

最新文章

  1. LIVE555再学习 -- testOnDemandRTSPServer 源码分析
  2. mysql5.7.25my.ini_mysql5.7 没有my.ini 的解决办法
  3. mysql导入创建表空间_oracle创建表空间 导入数据库
  4. rust怎么上邮轮_20年内泰坦尼克号将消失 英公司推三千米沉船之旅
  5. 【转载】关联分析中的支持度、置信度和提升度
  6. hive的安装和升级
  7. aws rds监控慢sql_估算AWS RDS SQL Server成本
  8. Win10 安装 VS2015 失败解决办法
  9. Vue Document
  10. Python设计模式(七)【命令模式】
  11. win7无法删除文件夹,提示“找不到该项目”
  12. Typora的历史版本下载地址
  13. 电脑linux 开启热点hostapt,Ubuntu16.04开启热点
  14. 虚拟滚动列表和css虚拟滚动【有思考】
  15. python怎么横着输出_对python3中, print横向输出的方法详解
  16. 计算机打印机能不能取消正在,删除HP打印机驱动程序. 打印机驱动程序正在使用中,无法删除...
  17. 真刑!又一个程序员同行要进去了
  18. Elasticsearch的使用RestHighLevelClient
  19. 怎么html让元素脱离文档流,子元素设置绝对定位之后脱离文档流!
  20. QuickBooks qbo api transactionlist 获取数据不全的问题

热门文章

  1. C#中要使一个类支持FOREACH遍历,实现过程怎样? [转]
  2. 博客开通了....激动 呵呵
  3. 【数据结构与算法】之深入解析“下一个更大元素I”的求解思路与算法示例
  4. Swift之深入解析内存管理的底层原理
  5. LeetCode Algorithm 118. 杨辉三角
  6. 2 0 2 0 年 第 十 一 届 蓝 桥 杯 - 国赛 - CC++大学B组 - B.扩散
  7. Django安装与使用
  8. 深度学习——02、深度学习入门——经典卷积神经网络架构实例——AlexNet
  9. Keil 5安装激活教程
  10. 解决VS2017运行时控制台一闪即逝问题的方法