Python中的@函数装饰器到底是什么?

Stella981
• 阅读 783

在解释@函数装饰器之前,先说一下,类中的类方法和静态方法。

在Python中完全支持定义类方法、静态方法。这两种方法很相似,Python它们都使用类来调用(ps:用对象调用也可以)。

区别在于:Python会自动绑定类方法的第一个参数,类方法的第一个参数会自动绑定到类本身;但对于静态方法则不会自动绑定。

类方法用@classmethod修饰,静态方法用@staticmethod修饰,如下:

 1 #coding=utf-8
 2 class Person:
 3     @classmethod
 4     def eat(cls):
 5         print("类方法eat:",cls)
 6         
 7     @staticmethod
 8     def sleep(p):
 9         print("静态方法sleep:",p)
10 
11 
12 Person.eat()
13 Person.sleep("info")
14 
15 p = Person()
16 
17 p.eat()
18 p.sleep('info')

控制台打印如下:

Python中的@函数装饰器到底是什么?

解释:eat方法因为是@classmethod修饰所以它是类方法,所以第12行调用时,不用传入任何参数,即可以调用,因为它会自动绑定类本身到第一个参数。

sleep方法因为是@staticmethod修饰所以它是静态方法,所以在第13行调用时,需要传入参数。再看17、18行,可以得出结论:不管是用类或者对象调用静态方法,Python都不会对静态方法的第一个参数进行自动绑定。

  上面的@classmethod 和 @staticmethod 其实就是函数装饰器,其中classmethod和staticmethod为Python中内置的函数。

  使用@符号引用已有函数后,可用于修饰其他函数。

例如@函数A 装饰 函数B ,实际完成的步骤为:

1.将被装饰的函数B作为参数传给函数A

2.将函数B替换为第1步的返回值。

举个例子:

 1 def funA(fn):
 2     """参数为一个函数对象"""
 3     print('A')
 4     fn() #执行传入的fn函数
 5     return 'tizer'
 6     
 7 '''
 8 下面的代码相当于funA(funB)
 9 funB将会被替换为该语句的返回值
10 由于funA返回tizer,因此funB就是tizer
11 '''
12 @funA
13 def funB():
14     print('B')
15 print(funB)

先看运行结果:

Python中的@函数装饰器到底是什么?

解释:既然funB作为参数传给了funA,那就是得先执行funA中的代码,所以执行了print(‘A’),打印了A,然后执行第4行fn(),因为传入的funB,funB中的代码为print('B'),所以打印了B,然后funA 返回了一个字符串tizer,所以funB 等同于 tizer,第15行print(funB) 等同于 print('tizer'),所以打印了tizer。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
3年前
SpringBoot学习:整合shiro自动登录功能(rememberMe记住我功能)
首先在shiro配置类中注入rememberMe管理器!复制代码(https://oscimg.oschina.net/oscnet/675f5689159acfa2c39c91f4df40a00ce0f.gif)/cookie对象;rememberMeCookie()方法是设置Cookie的生成模
Wesley13 Wesley13
3年前
Java日期时间API系列31
  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前
Stella981 Stella981
3年前
Python3中的super()函数详解
关于Python3中的super()函数我们都知道,在Python3中子类在继承父类的时候,当子类中的方法与父类中的方法重名时,子类中的方法会覆盖父类中的方法,那么,如果我们想实现同时调用父类和子类中的同名方法,就需要使用到super()这个函数,用法为super().函数名()下面是一个例子:
Easter79 Easter79
3年前
SpringBoot学习:整合shiro自动登录功能(rememberMe记住我功能)
首先在shiro配置类中注入rememberMe管理器!复制代码(https://oscimg.oschina.net/oscnet/675f5689159acfa2c39c91f4df40a00ce0f.gif)/cookie对象;rememberMeCookie()方法是设置Cookie的生成模
Stella981 Stella981
3年前
PHP中static和self的区别
使用self::或者\_\_CLASS\_\_对当前类的静态引用,取决于定义当前方法所在的类:使用static::不再被解析为定义当前方法所在的类,而是在实际运行时计算的。也可以称之为“静态绑定”,因为它可以用于(但不限于)静态方法的调用。静态绑定是PHP5.3.0,增加的一个功能用于在继承范围内引用静态调用的类简单通俗的来说,
Stella981 Stella981
3年前
PythonStudy——魔法函数 Magic Methods
魔法函数python中以双下划线开始和结束的函数(不可自己定义)为魔法函数调用类实例化的对象的方法时自动调用魔法函数(感觉不需要显示调用的函数都叫)在自己定义的类中,可以实现之前的内置函数,比如下面比较元素sorted时用It函数(lt(self,other):判断self对象是否小于other对象;)
Stella981 Stella981
3年前
CI等MVC框架中为什么不能有index控制器的原因
因为类名称是index而方法又是index,这样index函数就是php4中的构造函数,即实例化类时,直接执行这个函数而没有执行父类的构造函数,也就没有初始化CI核心类。所以会提示没有定义属性或方法了。用index类名也可以,在publicfunctionindex()方法前加上,调用父类的构造方法publicfunction\_\
桥蕤 桥蕤
7个月前
Python类方法,静态方法和实例方法
类的方法可分为类方法,静态方法和实例方法;这样的分类可以让代码开发更加的简洁明了,观看代码更有层次感,方便日后的维护工作;一个类对象的行为即是该类的方法,类中的方法一般格式如下:pythonclass类名(参数):def方法名(参数):...1.类方法类方