chap 10 函数和函数式编程
1.python中什么都不返回的函数默认返回的对象类型是None;由于python当中的函数可以动态地确定类型而且函数能返回不同类型的值,所以函数的类型和返回值的类型没有进行直接的关联。在模拟c语言的函数重载时,要使用type()内建函数来做代理。
2.python中不允许在一个函数声明之前去调用这个函数。
3.函数体内部创建函数对象的方式:a.内部/内嵌函数 b.lambda函数
a.内部函数定义包含了外部函数里定义的对象的引用(这个对象甚至可以是在外部函数之外),内部函数会变成被称为闭包
4.装饰器:一般说来,当你包装一个函数的时候,你最终会调用它。最棒的是我们能在包装的环境下在合适的时机调用它。我们在执行函数之前,可以运行些预备代码,如 post-morrem 分析,也可以在执行代码之后做些清理工作。所以当你看见一个装饰器函数的时候,很可能在里面找到这样一些代码,它定义了某个函数并在定义内的某处嵌入了对目标函数的调用或者至少一些引用。从本质上看,这些特征引入了 java 开发者称呼之为 AOP(Aspect Oriented Programming,面向方面编程)的概念。你可以考虑在装饰器中置入通用功能的代码来降低程序复杂度 。例如,可以用装饰器来:引入日志、增加计时逻辑来检测性能、给函数加入事务的能力
adas装饰器以@开头,接着是装饰器函数的名字和可选的参数。紧跟着装饰器声明的是被修饰的函数,和装饰函数的可选参数。
eg.
@decorator(dec_opt_args)
def func2Bdecorated(func_opt_args):
装饰器可以堆叠起来:
eg.
@deco2
@deco1
def func(arg1, arg2, ...): pass
等价于:
def func(arg1, arg2, ...): pass
func = deco2(deco1(func))
带参数的装饰器,需要自己返回以函数作为参数的装饰器。换句话说,decomaker()用 deco_args 做了些事并返回函数对象,而该函数对象正是以 foo 作为其参数的装饰器。:
eg.
@decomaker(deco_args)
def foo(): pass
等价于:
foo = decomaker(deco_args)(foo)
5.传递函数:
因为所有的对象都是通过引用来传递的,函数也不例外.当对一个变量赋值时,实际是将相同对象的引用赋值给这个变量。如果对象是函数的话,这个对象所有的别名都是可调用的。foo()是对函数对象的调用,foo是函数对象的引用
我们甚至可以把函数作为参数传入其他函数来进行调用。
eg.
>>> def bar(argfunc):
... argfunc()
...
>>> def foo():
... print 'in foo'
...
>>>
>>> bar(foo)
in foo
6. 形式参数(位置参数、默认参数)
可变长度的参数:非关键字可变长参数(元组,函数调用中使用*来指定参数元组,所有的形式参数必须先于非正式的参数之前出现)、关键字变量参数(字典,函数调用中使用**来指定参数集合)
异常:只要在函数调用时给出不正确的函数参数数目,就会产生一个 TypeError异常
eg.
1.python中什么都不返回的函数默认返回的对象类型是None;由于python当中的函数可以动态地确定类型而且函数能返回不同类型的值,所以函数的类型和返回值的类型没有进行直接的关联。在模拟c语言的函数重载时,要使用type()内建函数来做代理。
2.python中不允许在一个函数声明之前去调用这个函数。
3.函数体内部创建函数对象的方式:a.内部/内嵌函数 b.lambda函数
a.内部函数定义包含了外部函数里定义的对象的引用(这个对象甚至可以是在外部函数之外),内部函数会变成被称为闭包
4.装饰器:一般说来,当你包装一个函数的时候,你最终会调用它。最棒的是我们能在包装的环境下在合适的时机调用它。我们在执行函数之前,可以运行些预备代码,如 post-morrem 分析,也可以在执行代码之后做些清理工作。所以当你看见一个装饰器函数的时候,很可能在里面找到这样一些代码,它定义了某个函数并在定义内的某处嵌入了对目标函数的调用或者至少一些引用。从本质上看,这些特征引入了 java 开发者称呼之为 AOP(Aspect Oriented Programming,面向方面编程)的概念。你可以考虑在装饰器中置入通用功能的代码来降低程序复杂度 。例如,可以用装饰器来:引入日志、增加计时逻辑来检测性能、给函数加入事务的能力
adas装饰器以@开头,接着是装饰器函数的名字和可选的参数。紧跟着装饰器声明的是被修饰的函数,和装饰函数的可选参数。
eg.
@decorator(dec_opt_args)
def func2Bdecorated(func_opt_args):
装饰器可以堆叠起来:
eg.
@deco2
@deco1
def func(arg1, arg2, ...): pass
等价于:
def func(arg1, arg2, ...): pass
func = deco2(deco1(func))
带参数的装饰器,需要自己返回以函数作为参数的装饰器。换句话说,decomaker()用 deco_args 做了些事并返回函数对象,而该函数对象正是以 foo 作为其参数的装饰器。:
eg.
@decomaker(deco_args)
def foo(): pass
等价于:
foo = decomaker(deco_args)(foo)
5.传递函数:
因为所有的对象都是通过引用来传递的,函数也不例外.当对一个变量赋值时,实际是将相同对象的引用赋值给这个变量。如果对象是函数的话,这个对象所有的别名都是可调用的。foo()是对函数对象的调用,foo是函数对象的引用
我们甚至可以把函数作为参数传入其他函数来进行调用。
eg.
>>> def bar(argfunc):
... argfunc()
...
>>> def foo():
... print 'in foo'
...
>>>
>>> bar(foo)
in foo
6. 形式参数(位置参数、默认参数)
可变长度的参数:非关键字可变长参数(元组,函数调用中使用*来指定参数元组,所有的形式参数必须先于非正式的参数之前出现)、关键字变量参数(字典,函数调用中使用**来指定参数集合)
异常:只要在函数调用时给出不正确的函数参数数目,就会产生一个 TypeError异常
eg.
def newfoo(arg1, arg2, *nkw, **kw):
'display regular args and all variable args'
print 'arg1 is:', arg1
print 'arg2 is:', arg2
for eachNKW in nkw:
print