def 函数名(参数):
函数体
函数体可以是pass,表示待执行,通常用于功能扩展
1、
isinstance(each_item,list) # 类型检查函数。判断each_item是否为一个list列表<span style="font-family:Microsoft YaHei;"><span style="font-size: 15px;"></span></span>
2、return 可以返回多个值,以tuple的形式。list[ ] tuple( ) dict{ }
3、函数的默认参数写法
def power(x, n=2)
power(5) # power(5,2)
power(5,3) # power(5,3)
4、默认参数必须指向不变对象! 可以用
None
这个不变对象来实现http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431752945034eb82ac80a3e64b9bb4929b16eeed1eb9000
为什么要设计
str
、None
这样的不变对象呢?因为不变对象一旦创建,对象内部的数据就不能修改,这样就减少了由于修改数据导致的错误。此外,由于对象不变,多任务环境下同时读取对象不需要加锁,同时读一点问题都没有。我们在编写程序时,如果可以设计一个不变对象,那就尽量设计成不变对象。
5、 list或tuple前面加一个
*
号,即变成可变参数,调用时传参更简单:
calc([1, 3, 5, 7]) / calc((1, 3, 5, 7)) ——> calc(1, 3, 5, 7)
6、关键字参数:扩展函数功能,参考注册时的可选项(必选参数必填、关键字参数可选)
**extra
表示把extra
这个dict的所有key-value用关键字参数传入到函数,通常包含其他可选信息,打印出来是一个dict形式,传入的时候也可以不是dict,如
>>> person('Adam', 45, gender='M', job='Engineer')
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}
7、判断一个key是否在dict中
<span style="font-family:Microsoft YaHei;">if 'city' in kw:</span>
8、命名关键字参数:
def person(name, age, *, city, job):
print(name, age, city, job)
9、
*args
是可变参数,args接收的是一个tuple/list;
**kw
是关键字参数,kw接收的是一个dict。
argu和kw都是习惯写法
10、解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。
求n!
def fact(n):
return fact_iter(n, 1)
def fact_iter(num, product):
if num == 1:
return product
return fact_iter(num - 1, num * product)
遗憾的是,大多数编程语言没有针对尾递归做优化,Python解释器也没有做优化,所以,即使把上面的
fact(n)
函数改成尾递归方式,也会导致栈溢出。
11、小结
使用递归函数的优点是逻辑简单清晰,缺点是过深的调用会导致栈溢出。
针对尾递归优化的语言可以通过尾递归防止栈溢出。尾递归事实上和循环是等价的,没有循环语句的编程语言只能通过尾递归实现循环。
Python标准的解释器没有针对尾递归做优化,任何递归函数都存在栈溢出的问题。
汉罗塔问题
声明:学习廖雪峰的Python教程——Python函数章节后的学习笔记,感谢Micheal Liao.