1. 创建函数

一个函数代表一个行为并且返回一个结果(包括None),在Python中使用def关键字来定义一个函数,如下:

def hello(name):
print 'hello,' + name + '!'

接下来调用函数,并查看其返回值:

# output:
# hello,gy!
# None
print hello('gy')

可以看到hello函数首先打印了:Hello,gy!,然后我们又将其返回值也打印出来,在这里因为没有返回具体的值,所以返回了None

下面我们可以定义一个用于计算斐波那契数列的函数,接收计算的位数(参数),返回计算的结果(返回值),如下:

 def fibs(num):
result = [0,1]
for i in range(num - 2):
result.append(result[-2] + result[-1])
return result # output: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
print fibs(10)

2. 文档字符串

文档字符串指的是在函数开头写下该函数的说明字符串,该字符串会作为函数的一部分进行存储。可以通过调用__doc__属性来查看:

 def fibs(num):
"根据指位数来计算斐波那契数列"
result = [0,1]
for i in range(num - 2):
result.append(result[-2] + result[-1])
return result # 输出:根据指位数来计算斐波那契数列
print fibs.__doc__

3. 参数

函数使用参数来传递信息,而参数类型又基本分为两大类型:可变类型参考和不可变类型参数。

3.1 不可变类型参数

不可变类型(字符串、数字和元组等)是不可变的,即无法修改,只能使用新的值来覆盖。使用不可变类型作为函数的参数时:在函数内为参数赋值不会改变其外部变量的值,如下:

 # 字符串是不可变的
def try_to_change(n):
n = 'Gumby' name = 'Sunshine' # 尝试改变参数的值
try_to_change(name) # output: Sunshine(函数内部的改变对其没有影响)
print name

3.2 可变类型参数

可变类型参数(列表等)指的是:使用可变的数据结构来作为函数的参数使用。在函数内部修改可变类型参数的值时,会同时改变其外部变量的值(因为它们引用的其实是同一个对象),如下所示:

 # 列表是可变的
def try_to_change2(n):
n[0] = 'Sunshine' person = ['Gumby','Bob']
# 尝试改变参数的值
try_to_change2(person) # output: ['Sunshine', 'Bob']
# 函数内部的改变会作用于外部的变量
print person

如果想避免上面的情况可以对需要作为可变类型的参数的对象复制一个副本,这里是列表可以通过对其进行切片来返回一个新的副本,如下:

 # 将可变的数据结构(列表)用作参数
def try_to_change2(n):
n[0] = 'Sunshine' person = ['Gumby','Bob']
n = person[:] # 通过切片返回新的副本
try_to_change2(n)
print person # ['Gumby', 'Bob']
print n # ['Sunshine', 'Bob']
print n is person # False

3.3 关键字参数和默认值

在我们之前使用参数的形式是:位置参数,即调用该函数给其传值时,是根据输入的值的先后顺序来给参数一一赋值 的。不过有时候如果我们需要定义的函数有大量的参数时,传值时只是于依赖于顺序的话是比较容易出错的。同时如果部分参数在不多数情况下值都是一样的,每次 调用都需要重新赋值也比较麻烦。针对于这种情况Python为我们提供了两个语法糖:即关键字参数默认值。(PS:C#4.0新增的两个特性:具名参数和可选参数,和Python的这两个语法糖很类似,感兴趣的同学可以参考这里:《Effective C#》读书笔记——条目10:使用可选参数减少方法重载的数量<C#语言习惯>)。

使用关键字参数不需要对函数进行任何修改,只需要在调用函数时显示为参数赋值即可(不依赖特定顺序),如下:

 def hello(gretting,name):
print "%s,%s!" % (gretting,name) # output: hello,world!
hello(name='world',gretting='hello')

可以看到虽然调用时代码变多了,但是每个参数的含义一目了然。不过有时候我们的函数有些参数在大部分情况下使用同样的值,有时候也需要改变,这时候使用默认值,可以很好的解决这种问题,如下:

 def hello(gretting = 'hello',name='world'):
print "%s,%s!" % (gretting,name) hello() # hello,world!
hello(name = 'Sunshine') # hello,Sunshine!
hello('Greetings') # Greetings,world!

可以看到,如果没有给任何值的话,函数自动使用默认值,也可以通过关键字参数指定部分值,其他的依然使用默认参数,这为我们的方法调用提供了很大的灵活性。

3.4 使用任意参数列表

前面介绍的参数的个数基本都是固定的,有时候可以接收任意多的参数也是很有必要的,这时候可以使用Python为我们提供的语法糖(*号)来实现:

 def print_params(number,*params):
print number
print params # output:
#
# (1, 2, 3, 4, 5, 6)
print_params(6,1,2,3,4,5,6) # output:
#
# ()
print_params(0)

我们可以看到参数前的*号将所有的值放置到一个元组中(可以理解为将其他的参数收集起来)。如果没有为*号后的参数赋值则其值为一个空的元组。不过使用一个*号这样的语法不能处理关键字参数,如下:

 def print_params(*params):
print params # TypeError: print_params() got an unexpected keyword argument 'params'
print_params(params = (1,2,3))

解决的办法很简单,使用**来修饰参数即可,如下所示:

 # -- coding: utf-8 --
def print_params(**params):
print params
print type(params) # output: {'params': (1, 2, 3)}
# output: <type 'dict'>
print_params(params = (1,2,3))

可以看到使用**修饰的参数本质上其实是一个字典类型。可以通过这个字典来收集参数。

3.5 解包参数列表

除了通过才定义函数的参数(形参)前添加*或者**来收集参数,我们还可以在调用函数时在实参前调解这两个操作符,它们表示其对应的逆过程。如下所示:

 def add(x,y):
print x + y params = (1,2) # output: 3
add(*params)

通过使用*操作符我们将params参数分割了add函数所需的两个参数,同样我们也可以使用**操作符来分割字典对象:

 def hello(greeting,name):
print '%s,%s' %(greeting,name) params = {'greeting':'hello','name':'world'} # output: hello,world
# 这里使用*操作符也是可以的
hello(**params)

参考资料&进一步阅读

Python基础教程(第二版)

Python入门教程——深入函数定义

【循序渐进学Python】6.Python中的函数的更多相关文章

  1. python开发_python中的函数定义

    下面是我做的几个用列: #python中的函数定义,使用和传参 def_str = '''\ python中的函数以如下形式声明: def 函数名称([参数1,参数2,参数3......]): 执行语 ...

  2. python 在机器学习中应用函数

    浅述python中argsort()函数的用法 (1).先定义一个array数据 1 import numpy as np 2 x=np.array([1,4,3,-1,6,9]) (2).现在我们可 ...

  3. python unittest框架中addCleanup函数详解

    接上一篇doCleanups说明,这次介绍下另一个很好用的函数:addCleanup 还是老规矩,看官方文档说明: addCleanup(function, *args, **kwargs)¶ Add ...

  4. python 利用matplotlib中imshow()函数绘图

    matplotlib 是python最著名的2D绘图库,它提供了一整套和matlab相似的命令API,十分适合交互式地进行制图.而且也可以方便地将它作为绘图控件,嵌入GUI应用程序中.通过简单的绘图语 ...

  5. (转)python类class中_init_函数以及参数self的简单解释

    1)_init_函数(方法) #-*- encoding:utf-8 -*- class NewClass(object): def __init__(self,name): print self s ...

  6. python通过mongoengine中connect函数连接多个数据库

    mongoengine支持程序同时连接多个数据库,这些数据库可以位于一个或多个mongo之中,通过alias名称区分不同的连接即可. 可以通过switch_db切换到不同的数据库,进行读写操作,swi ...

  7. python和numpy中sum()函数的异同

    转载:https://blog.csdn.net/amuchena/article/details/89060798和https://www.runoob.com/python/python-func ...

  8. Python -- 使用模块中的函数

    在确定自己不会导入多个同名函数(从不同模块导入)的情况下,你可能不希望在每次调用函数的时候,都要写上模块的名字.那么,可以使用import命令的另外一种形式: >>> from ma ...

  9. 关于python使用threadpool中的函数单个参数和多个参数用法举例

    1.对单个元素的函数使用线程池: # encoding:utf-8 __author__='xijun.gong' import threadpool def func(name): print 'h ...

  10. Python函数式编程中map()、reduce()和filter()函数的用法

    Python中map().reduce()和filter()三个函数均是应用于序列的内置函数,分别对序列进行遍历.递归计算以及过滤操作.这三个内置函数在实际使用过程中常常和“行内函数”lambda函数 ...

随机推荐

  1. SSH乱码解决

    解决方案: 使用linux,在用户根目录(/root)下有一个.bash_profile配置文件,该配置只对当前用户有效. 使用ls -a命令可以查看到该文件.使用vi编辑器打开该文件后,在其中加入 ...

  2. WPF快速精通版

    命名空间: xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:local="clr-namespace:U ...

  3. 如何启动ResourceManager和NodeManager

    登录到bigtop1上,vagrant ssh bigtop1 将/usr/lib/hadoop/libexec/init-hdfs.sh文件内容替换为: #!/bin/bash -ex # # Li ...

  4. 解决企业In-House安装APP需HTTPS支持的问题(转载)

    同事写的一篇文章,感觉不错,转过来. 解决企业In-House安装APP需HTTPS支持的问题 问题背景: 能否通过应用服务器发布企业应用: 解决iOS7.1后,发布地址必须为HTTPS服务器. 写作 ...

  5. 给The Lab Renderer for Unity中地形添加阴影

    The Lab Renderer for Unity是Valve针对VR在Unity的体验渲染器,提高VR的渲染效率,更多的大家可以查相应资料,在这,说个The Lab Renderer for Un ...

  6. 安装vs2013以后,链接数据库总是报内存损坏,无法写入的错误

    安装vs2013以后,链接数据库总是报内存损坏,无法写入的错误 这个错误几个月以前解决过一次,但是到又碰到的时候,竟然完全忘记当时怎么解决的了, 看来上了年纪记忆真是越来越不行了... 解决方案很简单 ...

  7. php 图片添加文字水印 以及 图片合成(微信快码传播)

    1.图片添加文字水印: $bigImgPath = 'backgroud.png'; $img = imagecreatefromstring(file_get_contents($bigImgPat ...

  8. [转]YII2 常用数据库操作

    1.对象操作: //1.简单查询 $admin=Admin::model()->findAll($condition,$params); $admin=Admin::model()->fi ...

  9. There is an internal error in the React performance measurement code.Did not expect componentDidMount timer to start while render timer is still in progress for another instance

    一.There is an internal error in the React performance measurement code.Did not expect componentDidMo ...

  10. php生成随机密码(php自定义函数)转自先锋教程网

    php生成随机密码(php自定义函数) 时间:2015-12-16 20:43:49来源:网络 导读:php随机密码的生成代码,使用php自定义函数生成指定长度的随机密码,密码规则为小写字母与数字的随 ...