函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。学会使用函数可以大大提高代码的复用性。在前面的学习中我们或多或少都接触到并使用了Python提供的内建函数,比如print()、dir()、type()等,但你也可以自己创建函数,这被叫做用户自定义函数。下面就来学习下如何自定义函数。

定义函数

规则如下:

(1)函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。

(2)任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。

(3)函数的第一行语句可以选择性地使用文档字符------用于存放函数说明。

(4)函数内容以冒号起始,并且缩进。

(5)return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。

  知道如上规则后是不是迫不及待的想定义一个函数了,不要着急,我们还是先来看看语法:

def functionname( parameters ):
  "函数_文档字符串"
  function_suite  
  return [expression]

  下面就举个列子:定义一个函数,传入参数,返回参数之和

def sum(a,b):
"计算两个数的和"
   return a+b

  既然定义了函数,是不是该调用了,下面就学习函数如何调用的:

调用函数

  这个函数的基本结构完成以后,你可以通过另一个函数调用执行,也可以直接从Python提示符执行。

# 定义函数
def sum(a,b):
"计算两个数的和"
   print a+b
   return
# 调用函数
sum(2,4)
# 运行结果
6

参数

  如上我们在调用函数sum()的时候,传入了两个整数,从而运行得出和。Python提供了多种参数类型,接下来我们一起学习下:

  在说到参数类型前,我们回忆下之前学习的内容中有提到可变和不可变的数据类型,如字符(string)和元组(tunple)是不可变的,而列表(list)和字典(dict)都是可变的。它们在作为参数传递时是有区别的:

  如不可变类型a='One'后再赋值a='Two'表明新生成了一个a,而不是改变了a的值,之前的a被舍弃了,作为参数传递其实是传递了一个复制的对象值过去,参数本身没有影响,即是内部改变;

  而可变类型a=[2,3,4]后赋值a=[6]表明列表元素有变动,而a本身没动,作为参数传递时将a本身传递过去,外部定义的a也会受到影响。

  说的有点绕,下面举例说明:

#定义不可变
def par(a):
   a=22
   print 'a=',a
   return
b=11
par(b)
print 'b=',b
#定义可变
def lis(L1):
   L1.append([2,3,4])
   print L1
   return
lis([11])
#运行结果
a= 22
b= 11
[11, [2, 3, 4]]

  明白了以上之后我们开始学习参数类型,必要参数、关键字参数、默认参数、不定长参数。

  必要参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。如上调用sum()函数,你必须传入两个参数,否则会出现如下语法错误:

Traceback (most recent call last):
 File "C:/Users/YangQing/PycharmProjects/Test/func.py", line 10, in <module>
   sum()
TypeError: sum() takes exactly 2 arguments (0 given)

  关键字参数和函数调用关系紧密,使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为Python 解释器能够用参数名匹配参数值。如下列子就是调用函数时使用参数名:

def info(name,age,hob):
   print 'name:',name+'\n'+'Age:',age+'\n'+'Hob:',hob
   return
#正常调用
info(name='John',age='20',hob='Football')
#运行结果
name: John
Age: 20
Hob: Football
#参数传递乱序调用
info(age='22',hob='Music',name='Kitt')
#运行结果
name: Kitt
Age: 22
Hob: Music

  从列子中可以看出,采用关键字参数类型时,传入的参数顺序是没有严格要求的。

  默认参数类型是指调用函数时如果不传递该参数,打印出的结果会采用默认值,如下例子:

def info(name,age=30,hob):
   print 'name:',name+'\n'+'Age:',age+'\n'+'Hob:',hob
   return
#传入参数
info(age='28',name='Haxi',hob='Reading')
#不传入参数
info(name='Hello',hob='Basketball')
#运行结果
name: Haxi
Age: 28
Hob: Reading
name: Hello
Age: 30
Hob: Basketball

  有时我们可能需要一个函数能处理比当初声明时更多的参数。这类参数就称为不定长参数,声明时加星号(*)的变量名会存放所有未命名的变量参数。如下例子:

def cla(num,*name):
   print str(num)+'班人员:'
   for i in name:
        print i
   return
#单个参数调用
cla(3,'John')
#多参数调用
cla(2,'Haxi','Xiaoli','Wuyang','Wangxin')
#运行结果
3班人员:
John
2班人员:
Haxi
Xiaoli
Wuyang
Wangxin