函数
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_string Out[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/<ipython console> in <module>() NameError: name 'x' is not defined In [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]: 2 In [66]: foo(3) Out[66]: 3 In [67]: foo() --------------------------------------------------------------------------- TypeError Traceback (most recent call last) /home/caribbean/<ipython console> in <module>() 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.
In [109]: issubclass(int,object) Out[109]: True In [110]: def foo(): .....: pass .....: In [111]: foo.__class__ Out[111]: <type 'function'> 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]: 3 In [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]: foo Out[168]: <function inner at 0x1d488c0> 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.fu foo.func_closure foo.func_defaults foo.func_doc foo.func_name foo.func_code foo.func_dict foo.func_globals In [16]: foo.func_closure Out[16]: (<cell at 0x1525be8: int object at 0xf9f338>,)
In [24]: def outer(x): ....: def inner(): ....: print x ....: return inner ....: In [25]: print1 = outer(1) In [26]: print2 = outer(2) In [27]: print1() 1 In [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_func Out[52]: 2
In [55]: foo = outer(foo) In [56]: foo Out[56]: <function inner at 0x1516b90>
可以把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]: 3 In [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.
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]: 20 In [66]: foo1(1) Argument were: (1,), {} Out[66]: 1 In [67]: foo2() Argument were: (), {} Out[67]: 2
参考资料:
http://www.simeonfranklin.com/blog/2012/jul/1/python-decorators-in-12-steps/