python中的@

个人知识库

Author: 刘杰文, Date: Unknown, Categories: , Tags:

python中的@

我的结论(Click Here)

横行霸道的鸟img于 2019-04-16 15:37:50 发布img42746img 收藏 173img

转https://www.cnblogs.com/mxh1099/p/5685619.html

https://blog.csdn.net/star714/article/details/71045305

一、函数修饰符

  ’@’ 用做函数的修饰符,可以在模块或者类的定义层内对函数进行修饰,

  出现在函数定义的前一行,不允许和函数定义在同一行

  一个修饰符就是一个函数,它将被修饰的函数作为参数,并返回修饰后的同名函数或其他可调用的东西?

  

要了解python中@装饰器的作用,首先要记住这么几点

\1. 装饰器符号“@”属于语法糖,什么意思呢?就是说,我不按照@装饰器的语法要求来写,而是按照一般python的语法要求来写完全可以。那么用@装饰器的格式来写的目的就是为了书写简单方便

\2.装饰器的作用是什么呢? 简单的理解就是:装饰原有的函数。什么意思呢?比如有一个函数func(a, b),它的功能是求a,b的差值,我现在有一个需求,就是想对函数功能再装饰下,求完差值后再取绝对值,但是不能在func函数内部实现,这时候就需要装饰器函数了,比如func = decorate(func)函数,将func函数作为参数传递给decorate函数,由decorate来丰富func函数,丰富完成后再返回给func,此时func的功能就丰富了。

3.==python的常识,函数和其他任何东西一样,都是对象。这意味着可以将函数当做实参传递给函数,或者在函数中将函数作为返回值返回。==例码验证:

>>> def add(x, y):
...   return x + y
>>> def sub(x, y):
...   return x - y
>>> def apply(func, x, y): # 1
...   return func(x, y) # 2
>>> apply(add, 2, 1) # 3
3
>>> apply(sub, 2, 1)
1

了解上述观点后,可以先不用@符号来写一个简单的装饰器

img

img

对于sub = decorate(sub)的理解。 最终会将inner的值传给sub ,此时执行sub(3, 4),其实是执行decorate中的inner,所以为1.

那么为了书写方便,将sub=decorate(sub)换为@decorate,并放在sub的定义面前,即:

@decorate
def sub(a, b):
  return a-b

img

img

只是书写不同,结果相同。

示例2: 

1 def square_sum(fn):
 2     def square(*args):
 3         print "1---", args
 4         n = args[0]
 5         # return n*(n-1)*(2*n-1)/6
 6         print "2==", n*(n-1)*(2*n-1)/6
 7         print fn.__name__
 8         fn(n*(n-1)*(2*n-1)/6)
 9         print "*"*15
10         return fn(n*(n-1)*(2*n-1)/6)
11     return square
12 
13 
14 @square_sum
15 def sum_a(a):
16     print "3=", a
17     
18 sum_a(10)

结果

   
1 1-– (10,)
2 2== 285
3 sum_a
4 3= 285
5 *******
6 3= 285

  可以看出,他是先执行修饰器函数,然后有return fn的时候,修饰器下的函数才是生效的,否则函数sum_a 是没有结果的。

End

样例:

def decorate(func):
    def inner(a, b):
        ret = func(a, b)
        return abs(ret)
    return inner

def sub(a ,b):
    pass
ret = decorate(sub)
print(ret(a, b))
# 当ret是sub时,就等于@修饰
# 即
@decorate
def sub(a, b):
	pass

如:

@decorate(para)
def sub(a, b):
	pass
# 表示,sub函数使用decorate函数修饰(即处理),处理时提供para参数供使用,最后返回新的函数(来自内层),调用正常调用,和这里的定义加修饰无关。

更多解读

http://c.biancheng.net/view/2270.html

特别内容

样例:

https://www.jianshu.com/p/5c0083eb76fe

def func0(cls: class):
    def decorator(func):
        def inner(arg):
            func(arg)
        return inner
    return decorator
def info(params):
    pass

decorator = func0(cls_A)
info = decorator(info)
# info = inner
@func0(cls_A)
def info(params):
	pass
# 即: 
# info = (func0(cls_A))(info)
# 即:
# info = func0(cls_A).__call__(info)