函数
In [24]: def foo(): ....: return 1 ....: In [25]: foo()Out[25]: 1
2.函数的作用域
In [62]: a_string = "This is a global variable"In [63]: def foo(): ....: print locals() ....: ....: In [64]: print globals()-------> print(globals()){''''''''''''''' u'a_string = "This is a global variable"\n', '_oh': {}, 'Out': {}}In [65]: foo(){}In [66]:
3.变量的解析规则
In [75]: a_string = "This is global variable"In [76]: def foo(): ....: print a_string ....: ....: In [77]: foo()This is global variable
In [87]: a_string = "This is global variable"In [88]: def foo(): ....: a_string = "test" ....: print locals() ....: ....: In [89]: foo(){'a_string': 'test'}In [90]: a_stringOut[90]: 'This is global variable'
4.变量的生命周期
In [117]: def foo(): .....: x = 1 .....: .....: In [118]: foo()In [119]: print x--------> print(x)---------------------------------------------------------------------------NameError Traceback (most recent call last)/home/caribbean/in ()NameError: name 'x' is not definedIn [120]:
5.函数的实参和形参 arguments and parameters
python可以允许传递参数给函数,这个参数就是arguments . 函数的参数变量就就是parameter
In [27]: def foo(x): ....: print locals() ....: ....: In [28]: foo(1){'x': 1}
In [64]: def foo(x,y=0): ....: return x -y ....: In [65]: foo(3,1)Out[65]: 2In [66]: foo(3)Out[66]: 3In [67]: foo()---------------------------------------------------------------------------TypeError Traceback (most recent call last)/home/caribbean/in ()TypeError: foo() takes at least 1 argument (0 given)In [68]: foo(y=1,x=3)Out[68]: 2
6.嵌套函数
In [73]: def outer(): ....: x = 1 ....: def inner(): ....: print x ....: ....: inner() ....: ....: In [74]: outer()1
7.
Functions are first class objects in Python
In [109]: issubclass(int,object)Out[109]: TrueIn [110]: def foo(): .....: pass .....: In [111]: foo.__class__Out[111]:In [112]: issubclass(foo.__class__,object)Out[112]: True
In [119]: def add(x,y): .....: return x + y .....: In [120]: def sub(x,y): .....: return x - y .....: In [121]: def apply(func,x,y): .....: return func(x,y) .....: In [122]: apply(add,2,1)Out[122]: 3In [123]: apply(sub,2,1)Out[123]: 1
函数可以作为参数传递给另一个函数,也可以返回一个函数
In [166]: def outer(): .....: def inner(): .....: print "Inside inner" .....: return inner .....: In [167]: foo = outer()In [168]: fooOut[168]:In [169]: foo()Inside inner
8.function closures
In [14]: def outer(): ....: x = 1 ....: def inner(): ....: print x ....: return inner ....: In [15]: foo = outer()In [16]: foo.fufoo.func_closure foo.func_defaults foo.func_doc foo.func_namefoo.func_code foo.func_dict foo.func_globals In [16]: foo.func_closureOut[16]: (,) |
In [24]: def outer(x): ....: def inner(): ....: print x ....: return inner ....: In [25]: print1 = outer(1)In [26]: print2 = outer(2)In [27]: print1()1In [28]: print2()2
9.装饰器
A decorator is just a callable that takes a function as an argument and returns a replacement function.
In [48]: def outer(some_func): ....: def inner(): ....: print "before some_func" ....: ret = some_func() ....: return ret + 1 ....: return inner ....: In [49]: In [50]: def foo(): ....: return 1 ....: In [51]: decorated = outer(foo)In [52]: decorated()before some_funcOut[52]: 2
In [55]: foo = outer(foo)In [56]: fooOut[56]:
可以把decorated变量理解成为foo的一个装饰过的版本
In [73]: class Coordinate(object): ....: def __init__(self,x,y): ....: self.x = x ....: self.y = y ....: ....: def __repr__(self): ....: return "Coord: " + str(self.__dict__) ....: ....: In [74]: def add(a,b): ....: return Coordinate(a.x + b.x,a.y + b.y) ....: In [75]: def sub(a,b): ....: return Coordinate(a.x - b.x,a.y - b.y) ....: In [76]: one = Coordinate(100,200)In [77]: two = Coordinate(300,200)In [78]: add(one,two)Out[78]: Coord: {'y': 400, 'x': 400}In [79]: In [80]: one = Coordinate(100,200)In [81]: two = Coordinate(300,200)In [82]: three = Coordinate(-100,-100)In [83]: sub(one,two)Out[83]: Coord: {'y': 0, 'x': -200}In [84]: add(one,three)Out[84]: Coord: {'y': 100, 'x': 0}
In [106]: def wrapper(func): .....: def checker(a,b): .....: if a.x < 0 or a.y < 0: .....: a = Coordinate(a.x if a.x > 0 else 0,a.y if a.y > 0 else 0) .....: if b.x < 0 or b.y < 0: .....: b = Coordinate(b.x if b.x > 0 else 0,b.y if b.y > 0 else 0) .....: ret = func(a,b) .....: if ret.x < 0 or ret.y < 0: .....: ret = Coordinate(ret.x if ret.x > 0 else 0, ret.y if ret.y .....: return ret .....: return checker .....: In [107]: add=wrapper(add)In [108]: sub=wrapper(sub)In [109]: sub(one,two)Out[109]: Coord: {'y': 0, 'x': 0}In [110]: add(one,three)Out[110]: Coord: {'y': 200, 'x': 100}
10. @符号应用到一个函数的装饰器上
在以上的例子中
add=wrapper(add)
可以写成
In [142]: @wrapper .....: def add(a,b): .....: return Coordinate(a.x + b.x,a.y + b.y) .....:
11. *args 和 **kwargs
在以上的例子中,对函数add()和sub()写了一个装饰器wrapper,这两个函数都只带两个参数。如果想要一个装饰器对任何函数都起作用,
In [16]: def one(*args): ....: print args ....: ....: In [17]: one()()In [18]: one(1,2,3)(1, 2, 3)In [19]: def two(x,y,*args): ....: print x,y,args ....: ....: In [20]: two('a','b','c')a b ('c',)
In [27]: def add(x,y): ....: return x + y ....: In [28]: lst = [1,2]In [29]: add(lst[0],lst[1])Out[29]: 3In [30]: add(*lst)Out[30]: 3
* 代表位置参数
** 代表字典和键值对
In [36]: def foo(**kwargs): ....: print kwargs ....: ....: In [37]: foo(){}In [38]: foo(x=1,y=2){'y': 2, 'x': 1}
In [44]: dct = { 'x' :1, 'y' :2 }In [45]: def bar(x,y): ....: return x + y ....: In [46]: In [47]: bar(**dct)Out[47]: 3
12.
More generic decorators
In [62]: def logger(func): ....: def inner(*args,**kwargs): ....: print "Argument were: %s, %s" % (args,kwargs) ....: return func(*args,**kwargs) ....: return inner ....: In [63]: @logger ....: def foo1(x,y=1): ....: return x * y ....: In [64]: @logger ....: def foo2(): ....: return 2 ....: In [65]: foo1(5,4)Argument were: (5, 4), {}Out[65]: 20In [66]: foo1(1)Argument were: (1,), {}Out[66]: 1In [67]: foo2()Argument were: (), {}Out[67]: 2
参考资料: