之前给出一个链接, 现在尝试用自己方式梳理一下 # 有时爱用蹩脚的英文注释, 唔.
>>
# 先从函数说起
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