python中的类装饰器应用场景_如何理解Python装饰器?

之前给出一个链接, 现在尝试用自己方式梳理一下 # 有时爱用蹩脚的英文注释, 唔.

>>

# 先从函数说起

def foo1():

print('this is a function')

foo1() # print ... in console.

'这是一种最为简单的函数-- 不涉及到任何变量, 参数 只是做了一件不以为然的事儿'

# 函数的域 作用范围 以及一个局部变量

global_string = 'this is a global string, my name is global_string'

def foo2():

# lets see its locals variable

# local variable in foo2

x = 3

print('foo2 locals:', locals())

foo2() # foo2 locals: {'x': 3}

print('-'*40)

# check global variable # gets a dictionary, and global_string inside.

# print('globals:' , globals())

# 一个变量的生存的周期

def foo3():

x = 3

print("x value:" , x)

foo3()

'try to run x += 3'

# x += 5, uncomment when you run.

# get NameError -- x is not defined = x is dead.

# 下面来看带有参数的函数

def foo4(s):

print('', s)

foo4('foobar')

## 或者可以多个参数, 甚至是默认的

def foo5(s, repeat= 3):

print('', s*repeat)

foo5('foobar')

'if call a function with un-matched arguments, error comes'

# foo5(1,2,3) # TypeError: foo5() takes from 1 to 2 positional arguments but 3 were given

'foo5 能接收1-2个参数, 大哥你给了3个. typeerror'

# 嵌套函数

def outer():

x = 71

def inner():

print('hello, i am inner')

print('outer variable x ',x)

inner()

outer()

'可以看到 内部函数能够访问外部函数的变量'

# 把函数当作一个对象

'查看类的属性 __class__ built-in function'

i = 3

print(i.__class__) #

print(outer.__class__) #

'''

# ==> 所以 既然 一个整数i 可以当作某函数的参数,

那么 这里的 函数 outer 当然也可以作为某个函数的参数!

'''

def applyfunc(func,args,repeat=3):

i = 0

repeat = 3 if repeat <= 1 else repeat

while i < repeat:

func(args)

i += 1

def test(s):

print('a test function', s)

applyfunc(test, 'love is important', repeat=3)

'可以看到 通过调用一个函数 applyfunc -- 让一个简单函数运行至少3次'

# Closures 不想翻译成闭包

def outer2():

x = 127

def inner2():

print(x)

return inner2

foobar = outer2()

foobar # print nothing

print(foobar.__closure__) # (,)

'可以看到 foobar中封存了一个整数对象 int object at 0x......'

foobar() # print

'x 是outer2中的局部变量, 只有当outer2运行时 x才开始出现.'

## Closures-2

def outer(x):

def inner():

print('inner just print x:', x)

return inner

print1 = outer(1)

print2 = outer(2)

print(print1.__closure__) # int object at 0x5C3EC010>

print(print2.__closure__) # int object at 0x5C3EC020>,

print1()

print2()

#== closure 是Python中一种机制, 对enclosing variables 的一个'储藏柜'

# Decorators 终于到了装饰器

def outer(somefunc):

def inner():

print('have not run ', somefunc.__name__, end='\n')

result = somefunc()

print(result + ' finished' )

return inner

def foo6():

return 'i am foo6'

decorator = outer(foo6)

decorator()

'上例演示了decorator 基本作用 - 以函数作参数, 并且输出一个装饰后的新函数'

'就字面理解下, 原来的函数是个毛坯房 只有一床板凑合睡, 找2装修小工后,爽了.'

# decorator - 2 , look like more useful

class Point(object):

def __init__(self, x, y):

self.x = x

self.y = y

def __repr__(self):

return 'I am a {name}, my attributes: {dict}'.format(name = self.__class__.__name__, dict=self.__dict__)

## definition calculation

def add(a, b):

return Point(a.x + b.x, a.y+b.y)

p1 = Point(500, 10)

print(p1)

p2 = Point(30, -100)

print(add(p1,p2))

'Now we want to do some value-check, to make sure the x, y validation'

'比如我们现在只想要点运算时 作数值的检查: 要求点是 100*100这个范围的 (0-100 这个正方形内) ,对于异常作边界处理'

def wrapper(func):

def checker(a, b):

a. x = max(0, a.x) ; a. y = max(0, a.y)

a. x = min(100, a.x);a. y = min(100, a.y)

b. x = max(0, b.x) ; b. y = max(0, b.y)

b. x = min(100, b.x);b. y = min(100, b.y)

result = Point(a.x +b.x, a.y+b.y)

return result

return checker

add_decorator = wrapper(add)

p1 = Point(500, 10)

p2 = Point(30, -100)

# print(add(p1,p2))

print('decorator !')

print(add_decorator(p1, p2))

#=> after check, it becomes 100+30, 10+0

# 最后 @ 符号

'因为装饰会经常使用, 为了避免上述麻烦的装饰方法 就想到一个简写'

@wrapper

def add_checked(a, b):

return Point(a.x +b.x, a.y+b.y)

print('skilled decorator using @')

print(add_checked(p1, p2))

evernote 文字版, 习惯用这个存了.

'一步步理解Python中的Decorator'

原文参考:

# 'refer: simeonfranklin.com'

推荐阅读:

chapter 9 - Metaprogramming, 9.1 9.2 ...

以及一些类似的中文博客资料, 都比较相似, 如果了解更多还是希望广泛地去看一些函数编程(FP)的内容, 笔者之前在学Scala, 后来又去了解了一些Haskell的基础知识,

Python: 会打扮的装饰器 · FunHacks

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值