函数是组织好的,可以被重复使用的,用来实现单一或相关功能的代码块。
任何编程语言都提供了很多内嵌函数,同时还允许用户自己定义想要的函数。本节主要讲自定义函数。

1、定义函数的规则

我们自定义函数时,需要满足一些规则,否则编译器不会识别。
(1)函数代码块以def关键词开头,后接函数标识符名和圆括号()。
(2)任何传入实参和形参必须放在圆括号中。圆括号中写的是形参。
(3)函数的第一行语句可以选择性地使用文档字符串—-用于存放函数说明。
(4)函数内容以冒号起始,并且函数体要有缩进。
(5)return[expression]结束函数,选择性地返回一个值给调用者。不带表达式的return相当于返回None。

2、定义函数语法

语法:

def functionname( parameters ) :
   "函数文档字符串(即函数说明)"
   function_suite(函数体)
   return [expression]
 
  • 1
  • 2
  • 3
  • 4

默认情况下,参数值和参数名称是按函数声明中定义的顺序匹配起来的。

3、函数调用

函数被定义后,本身是不会自动执行的,只有在被调用后,才会被执行。
下面通过一个例子来讲解函数的调用。

def printStr(str1) :
  "打印任何传入的字符串"
  print str1
 
  • 1
  • 2
  • 3

调用上面的打印字符串函数
原函数在定义时,定义了一个形参str1,所以在调用函数时,也必须传入一个参数,否则会报错。

printStr("调用字符串打印函数")
 
  • 1

执行结果:

调用字符串打印函数
 
  • 1

4、传参

先来看两个例子。
实例1:传递变量

#!/usr/bin/python
#coding=utf-8

def changeNum(num) :
  num += 1
  print "自定义函数中的num = ",num

#定义变量num,赋初始值为10
num = 10
#
changeNum(num)
print "函数调用后num = ",num
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

执行结果:

自定义函数中的num =  11
函数调用后num =  10
 
  • 1
  • 2

实例2 :传序列list

#!/usr/bin/python
# -*- coding: utf-8 -*-
def changeList(list1) :
  list1.append('newStr')
  print "函数中的list :",list1

#定义变量num,赋初始值为10
list1 = [1,2,3]
print "调用函数前的list: ",list1
changeList(list1)
print "调用函数后的list:",list1
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

执行结果:

调用函数前的list:  [1, 2, 3]
函数中的list : [1, 2, 3, 'newStr']
调用函数后的list: [1, 2, 3, 'newStr']
 
  • 1
  • 2
  • 3

从上面的结果可以看出,在函数中改变num变量的值,但是在函数调用之外num变量的值却没有改变。而在第二个实例中,在函数中像list1中增加一个元素’newStr’,在函数外查看原list1,发现也增加了一个元素’newStr’。也就是说在函数中改变list1,原list1也跟着改变。但是从这样我们就能说在Python中,实例1是传值,实例2是传引用吗?

其实非也,和其他语言不一样,在Python中,一切皆对象, Python参数传递采用的都是“传对象引用”的方式。实际上,这种方式相当于传值和传引用的一种综合。如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值,相当于通过“传引用”来传递对象。如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象,相当于通过“传值’来传递对象,此时如果想改变这些变量的值,可以将这些变量申明为全局变量。

参考:

  1. Python 函数之函数定义、调用、传参
  2. Python3 函数