1、函数定义:
定义一个函数要使用def语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回,不带参数值的return语句返回None。
#1、定义无参函数: def person1():
print(“hello”)
return("hello") #调用return函数获取返回值 #2、定义有参函数: def person2(name):
print(“hello”,name)
return("hello",name) #调用return函数获取返回值
#3、函数的调用
person1()
person2("ryan")
#1、函数定义: def test(): "the funcation details" print("in the test funcation") return 0 ''' def #定义函数的关键字 test #函数名 () #定义形参,我这边没有定义。如果定义的话,可以写成:def test(x): 其中x就是形式参数 "the funcation details" # 文档描述(非必要,但是强烈建议你为你的函数添加详细信息,方便别人阅读) print #泛指代码块或者程序逻辑处理 return #定义返回值 ''' #2、过程定义: #定义过程 def test_2(): "the funcation details" print("in the test funcation") ''' 注:从上面两个例子看出来,函数和过程,无非就是函数比过程多了一个return的返回值,其他的也没什么不一样。 小结:不难看出,函数和过程其实在python中没有过多的界限,当有return时,则输出返回值,当没有return,则返回None '''
2、函数作用域
Python使用名称空间的概念存储对象,这个名称空间就是对象作用的区域,不同对象存在于不同的作用域。
每个模块都有自已的全局作用域。函数定义的对象属局部作用域,只在函数内有效,不会影响全局作用域中的对象。赋值对象属局部作用域,除非使用global关键字进行声明。在函数、类等内部可见局部作用域;局部变量使用范围不能超过其所在的局部作用域。
LGB 规则--大多数名字引用在三个作用域中查找:先局部(Local),次之全局(Global),再次之内置(Build-in)。
全局变量是位于模板文件内部的顶层的变量名;
全局变量如果在函数内部被赋值的话,必须经过声明;
全局变量在函数的内部不经过声明也可以被引用。
如想在局部作用域中改变全局作用域的对象,必须使用global关键字 。'global'声明把赋值的名字映射到一个包含它的模块的作用域中。若仍然找不到这个变量名,则引发NameError异常。
#coding=utf-8 name = "ryan" #全局变量 def fun(): country = "China" #局部变量 print name global name #声明全局变量 name = "joe" #修改全局变量 print name fun() print name
3、函数参数
#1、普通参数: # ######### 定义函数 ######### # name 叫做函数func的形式参数,简称:形参 def func(name): print(name) # ######### 执行函数 ######### # 'xiaoyao' 叫做函数func的实际参数,简称:实参 func('xiaoyao') #2、默认参数: def func(name, age = 18): print("%s:%s" %(name,age)) func('xiaoyao') # 默认参数在不指定的时候,就是默认值 func('xiaoyao',20) # 一旦指定,就不再使用默认值 #注:默认参数需要放在参数列表最后,可以有多个默认参数 #指定参数: def func(name, age): print("%s:%s" %(name,age)) func(age=20,name='xiaoyao') # 可以通过形参名称,不按顺序的传入参数 #3、动态参数(参数组): #(*args) 功能:接收N个位置参数,转换成元组的形式 def hello(*argv): print argv[0] print argv hello(3,3,4) #(**kwargs) 功能:把N个关键字参数,转换成字典形式 def hello(**kargv): print kargv.keys() print kargv.values() print kargv hello(a=1,b=3,c=4,d=0)
4、匿名函数
python 使用 lambda 来创建匿名函数。
lambda只是一个表达式,函数体比def简单很多。
lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。
虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
ambda函数的语法只包含一个语句,如下:
lambda [arg1 [,arg2,.....argn]]:expression
#!/usr/bin/python # -*- coding: UTF-8 -*- # 可写函数说明 sum = lambda arg1, arg2: arg1 + arg2; # 调用sum函数 print "相加后的值为 : ", sum( 10, 20 ) print "相加后的值为 : ", sum( 20, 20 )
5、嵌套函数
在一个函数中定义了另外一个函数
#coding=utf-8 def outer(): def inner(): print('inner') print('outer') inner() outer() inner() # 此句会出错,内部函数不能被外部直接使用,会抛NameError异常) #函数有可见范围,这就是作用域的概念
6、递归
递归调用是函数嵌套调用的一种特殊形式,如果一个函数在内部直接或间接调用自身,这个函数就是递归函数。
''' 场景:用10不断除以2,直到除不尽为止,打印每次结果。 思路: # 10/2=5 # 5/2=2.5 # 2.5/2=1.25 # ... ''' #用while循环实现: n = 10 while True: n = int(n/2) print(n) if n == 0: break ''' #输出 5 2 1 0 ''' #非递归方式实现: def calc(n): n = int(n/2) return n r1 = calc(10) r2 = calc(r1) r3 = calc(r2) r4 = calc(r3) print(r1) print(r2) print(r3) print(r4) ''' #输出 5 2 1 0 ''' #用递归实现: def calc(n): print(n) if int(n/2) == 0: #结束符 return n return calc(int(n/2)) #调用函数自身 m = calc(10) print('----->',m) ''' #输出 10 5 2 1 -----> 1 #最后返回的值 ''' #来看实现过程,我改了下代码 def calc(n): v = int(n/2) print(v) if v > 0: calc(v) print(n) calc(10) ''' #输出 5 2 1 0 1 2 5 10 ''' #递归层数: import sys print(sys.getrecursionlimit()) # 默认递归限制层数 sys.setrecursionlimit(1500) # 修改递归层数 #尾递归优化: #调用下一层时候退出。(解决栈溢出的问题,每次只保留当前递归的数据),在C语音里有用,Python中没用 def recursion(n): print(n) return recursion(n+1) recursion(1) ''' 递归特性: (1)递归就是在过程或者函数里调用自身 (2)在使用递归策略时,必须有一个明确的结束条件,称为递归出口 (3)每次进入更深一层递归时,问题规模相比上次递归都应有所减少(问题规模:比如你第1次传进的是10,第2次递归应该是9...依次越来越少,不能越来越多)。 (4)递归算法解题通常显得很简洁,但递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出),所以一般不倡导使用递归算法设计程序。 '''
递归算法一般用于解决三类问题:
(1)数据的定义是按递归定义的。(比如Fibonacci函数)
(2)问题解法按递归算法实现。(回溯)
(3)数据的结构形式是按递归定义的。(比如树的遍历,图的搜索,二分法查找等)
堆栈扫盲:http://www.cnblogs.com/lln7777/archive/2012/03/14/2396164.html