Python之--自定义函数:

在Python中,定义一个函数要使用def语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回。

以下自定义一个函数用于判断一个人是成年人好事青少年:

1 >>> defjudge_person(age):2 ... if age < 18:3 ... print("teenager!")4 ... else:5 ... print("adult!")6 ...7 >>> judge_person(12)8 teenager!9 >>> judge_person(23)10 adult!11 >>>

请注意,函数体内部的语句在执行时,一旦执行到return时,函数就执行完毕,并将结果返回。因此,函数内部通过条件判断和循环可以实现非常复杂的逻辑。

如果没有return语句,函数执行完毕后也会返回结果,只是结果为None。

return None可以简写为return

1 >>> defget_age(age):2 ... if age > 18:3 ... return "older"

4 ... else:5 ... return

6 ...7 >>> get_age(12)8 >>> get_age(56)9 'older'

10 >>>

空函数:

什么叫做”空函数“?所谓的空函数就是你定义一个函数,但是什么也不用做,就是定义了一个空函数!例如:

1 >>> defEmpty():2 ... pass

3 ...4 >>> defEmpty2():5 ... pass

6 ...7 >>>

pass语句什么都不做,那有什么用?实际上pass可以用来作为占位符,比如现在还没想好怎么写函数的代码,就可以先放一个pass,让代码能运行起来。

pass还可以用在其他语句里,比如:

1 >>> age = 90

2 >>> ifage:3 ... pass

4 ...5 >>> #如果没有pass就会报错。

6 ...7 >>> ifage:8 ...9 File "", line 2

10

11 ^

12 IndentationError: expected an indented block13 >>>

调用函数时,如果参数个数不对,Python解释器会自动检查出来,并抛出TypeError:

但是如果参数类型不对,Python解释器就无法帮我们检查。

当传入了不恰当的参数时,内置函数abs会检查出参数错误,而我们定义没有参数检查,所以,这个函数定义不够完善。

以下定义一个求绝对值的函数:

1 >>> defget_abs(value):2 ... if value <0:3 ... return -value4 ... else:5 ... returnvalue6

7 >>> get_abs(2)8 2

9 >>> get_abs(-3)10 3

11 >>>get_abs(0)12 013 >>>

让我们修改一下我们函数定义get_abs,对参数类型做检查,只允许整数和浮点数类型的参数。数据类型检查可以用内置函数isinstance实现:

1 >>>get_abs(dada)2 Traceback (most recent call last):3 File "", line 1, in

4 NameError: name 'dada' is notdefined5 >>> #在没有进行参数检查之前,报出了一个NameError:的错误

6 ... #以下我们对函数进行参数检查,提高函数的健壮性。

7 ...8 >>> defget_abc(value):9 ... if notisinstance(value,(int,float)):10 ... raise TypeError('参数类型不对,不好意思啊!')11 ... if value >=0:12 ... returnvalue13 ... else:14 ... return -value15 ...16 >>> #传入正确的参数:

17 ...18 >>> get_abc(12)19 12

20 >>> get_abc(-12)21 12

22 >>> #传入错误的参数:

23 >>> get_abc('gn')24 Traceback (most recent call last):25 File "", line 1, in

26 File "", line 3, inget_abc27 TypeError: 参数类型不对,不好意思啊!28 >>>

返回多个值:

比如在游戏中经常需要从一个点移动到另一个点,给出坐标、位移和角度,就可以计算出新的新的坐标:

1 importmath2

3 def move(x, y, step, angle=0):4 nx = x + step *math.cos(angle)5 ny = y - step *math.sin(angle)6 return nx, ny

例子:

1 >>> importmath2 >>>

3 >>> def move(x,y,step,angle =0):4 ... nx = x + step*math.cos(angle)5 ... ny = y - step*math.sin(angle)6 ... returnnx,ny7 ...8 >>> x1,y1 = move(100,10,60,math.pi/6)9 >>> printx1,y110 151.961524227 -20.0

11 >>>

其实,返回的值是一个元组(tuple)。

函数的参数:

定义函数的时候,我们把参数的名字和位置确定下来,函数的接口定义就完成了。对于函数的调用者来说,只需要知道如何传递正确的参数,以及函数将返回什么样的值就够了,函数内部的复杂逻辑被封装起来,调用者无需了解。

Python的函数定义非常简单,但灵活度却非常大。除了正常定义的必选参数外,还可以使用默认参数、可变参数和关键字参数,使得函数定义出来的接口,不但能处理复杂的参数,还可以简化调用者的代码。

1.默认参数:

定义一个计算平方的函数:power()

1 >>> defpower(x):2 ... return x*x3 ...4 >>> power(5)5 25

6 >>> power(7)7 49

8 >>>

当我们调用power函数时,必须传入有且仅有的一个参数x.但是此时我们要定义一个计算x的三次方甚至更多的次方该怎么办呢,或许聪明的读者已经想到了把power(x)修改为:power(x,n)实例如下:

1 >>> defpower(x,n):2 ... s = 1

3 ... while n >0:4 ... n = n-1

5 ... s = s *x6 ... prints7 ...8 >>> power(2,2)9 4

10 >>> power(2,9)11 512

12 >>> #但是此时想要使用power(x)求x的平方的话,该方法已经没有效果了。

13 ...14 >>> power(5)15 Traceback (most recent call last):16 File "", line 1, in

17 TypeError: power() takes exactly 2 arguments (1given)18 >>> #此处我们可以引入默认参数来解决这个问题:

19 ...20 >>> def power(x,n = 2):21 ... s = 1

22 ... while n >0:23 ... n -= 1

24 ... s *=x25 ... prints26 ...27 >>> power(5,2)28 25

29 >>> power(5)30 25

31 >>> #这样就可以实现效果了!是不是很帅!

而对于n > 2的其他情况,就必须明确地传入n,比如power(5, 3)。

从上面的例子可以看出,默认参数可以简化函数的调用。设置默认参数时,有几点要注意:

一是必选参数在前,默认参数在后,否则Python的解释器会报错(思考一下为什么默认参数不能放在必选参数前面);

二是如何设置默认参数。

当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数。

使用默认参数有什么好处?最大的好处是能降低调用函数的难度。

可见,默认参数降低了函数调用的难度,而一旦需要更复杂的调用时,又可以传递更多的参数来实现。无论是简单调用还是复杂调用,函数只需要定义一个。

默认参数虽然可以带来很大的便利,但是也有一个相当大的弊端:

先定义一个函数,传入一个list,添加一个END再返回:

1 >>> def add_end(L=[]):2 ... L.append(['END'])3 ... returnL4 ...5 >>> add_end([1,2,3])6 [1, 2, 3, ['END']]7 >>> add_end(['x','y','z'])8 ['x', 'y', 'z', ['END']]9 >>> #当你使用默认参数的时候,刚开始是对的:

10 ...11 >>>add_end()12 [['END']]13 >>> #但是再次调用add_end()时,结果就不对了

14 ...15 >>>add_end()16 [['END'], ['END']]17 >>>add_end()18 [['END'], ['END'], ['END']]19 >>>

默认参数是[],但是函数似乎每次都“记住了”上次添加了'END'后的list。这是为什么呢?

Python函数在定义的时候,默认参数L的值就被计算出来了,即[],因为默认参数L也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了。

所以,定义默认参数要牢记一点:默认参数必须指向不变对象!

要修改上面的例子,我们可以用None这个不变对象来实现:

1 >>> def add_end(L =None):2 ... if L isNone:3 ... L =[]4 ... L.append('END')5 ... returnL6 ...7 >>> #演示:

8 ...9 >>>add_end()10 ['END']11 >>>add_end()12 ['END']13 >>>add_end()14 ['END']15 >>>

为什么要设计str、None这样的不变对象呢?因为不变对象一旦创建,对象内部的数据就不能修改,这样就减少了由于修改数据导致的错误。此外,由于对象 不变,多任务环境下同时读取对象不需要加锁,同时读一点问题都没有。我们在编写程序时,如果可以设计一个不变对象,那就尽量设计成不变对象。

2. 可变参数:

在Python函数中可以传入默认参数,但是也可以传入可变参数.不难理解,可变参数的含义就是说,参数的个数时可以改变的,可以是1个、2个到任意个,还可以是0个。

我们以数学题为例子,给定一组数字a,b,c……,请计算a2 + b2 + c2 + ……。

要定义出这个函数,我们必须确定输入的参数。由于参数个数不确定,我们首先想到可以把a,b,c……作为一个list或tuple传进来,这样,函数可以定义如下:

在没有使用可变参数的情况:

1 >>> defget_value(numbers):2 ... sum =03 ... for n innumbers:4 ... sum += n *n5 ... returnsum6 ...7 >>> #但是调用的时候要先拼接一个元组或者列表

8 ...9 >>> get_value([1,2,3,4,5,6,7,8,9,10])10 385

11 >>> get_value((1,2,3,3,4,5,6))12 100

使用可变参数,把函数修改为如下:

1 >>> def get_value(*numbers):2 ... sum =03 ... for n innumbers:4 ... sum += n*n5 ... returnsum6 ...7 >>> get_value(1,2,3,4,5,6)8 91

定义可变参数和定义list或tuple参数相比,仅仅在参数前面加了一个*号。在函数内部,参数numbers接收到的是一个tuple,因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数:

1 >>> get_value(1)2 1 3 >>>get_value(0)4 0

但是,当你传入一个列表或者元组会出现错误:

1 >>> get_value([1,2,3,4,5,6])2 Traceback (most recent call last):3 File "", line 1, in

4 File "", line 4, inget_value5 TypeError: can't multiply sequence by non-int of type'list'6 >>> get_value((1,2,3,4,5,6))7 Traceback (most recent call last):8 File "", line 1, in

9 File "", line 4, inget_value10 TypeError: can't multiply sequence by non-int of type'tuple'11 >>>

可以这样解决列表和元组的问题:

1 >>> list1 = [8,9]2 >>> tuple1 = (1,2,3)3 >>>list14 [8, 9]5 >>>tuple16 (1, 2, 3)7 >>> get_value(list1[0],list1[1])8 145

9 >>> get_value(tuple1[0],tuple1[1],tuple1[2])10 14

11 >>>

但是,这种方法不是最好的,假如元组或者列表很大的时候就会出现工作量的问题,因此有一个更好的办法就是:Python允许你在list或tuple前面加一个*号,把list或tuple的元素变成可变参数传进去:

1 >>>list12 [8, 9]3 >>>tuple14 (1, 2, 3)5 >>> get_value(*tuple1)6 14

7 >>> get_value(*list1)8 145

9 >>>

有木有感觉python真的是无可挑剔啊,确实是这样的。

3. 关键字参数:

可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。请看示例:

1 >>> def person(name,age,**kw):2 ... print 'name:',name,'age:',age,'other:',kw3 ...4 >>> #函数person除了必选参数name和age外,还接受关键字参数kw。在调用该函数时,可以只传入必选参数:

5 ...6 >>> person('lt',20)7 name: lt age: 20other: {}8 >>>

也可以传入任意个关键字参数:

1 >>> person('lt',20,city = 'shanghai',height = 178,love = 'lt')2 name: lt age: 20 other: {'city': 'shanghai', 'love': 'lt', 'height': 178}3 >>> person('lt',20,city = 'shanghai',height = 178,love = 'lt',salary = 200000)4 name: lt age: 20 other: {'salary': 200000, 'city': 'shanghai', 'love': 'lt', 'height': 178}5 >>>

关键字参数有什么用?它可以扩展函数的功能。比如,在person函数里,我们保证能接收到name和age这两个参数,但是,如果调用者愿意提供更多的参数,我们也能收到。试想你正在做一个用户注册的功能,除了用户名和年龄是必填项外,其他都是可选项,利用关键字参数来定义这个函数就能满足注册的需求。

和可变参数类似,也可以先组装出一个dict,然后,把该dict转换为关键字参数传进去:

1 >>> kw = {'name':'lt','city':'shanghai','hometown':'xinnong','age':20}2 >>>kw3 {'city': 'shanghai', 'age': 20, 'name': 'lt', 'hometown': 'xinnong'}4 >>> person('jack',20,city=kw['city'],hometown = kw['hometown'])5 name: jack age: 20 other: {'city': 'shanghai', 'hometown': 'xinnong'}

但是,更简单便捷的方法时这样的:

1 >>> kw = {'city':'shanghai','hometown':'xingnong'}2 >>>kw3 {'city': 'shanghai', 'hometown': 'xingnong'}4 >>> person('Jack',12,**kw)5 name: Jack age: 12 other: {'city': 'shanghai', 'hometown': 'xingnong'}6 >>>

4.参数组合:

在Python中定义函数,可以用必选参数、默认参数、可变参数和关键字参数,这4种参数都可以一起使用,或者只用其中某些,但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数和关键字参数。

比如定义一个函数,包含上述4种参数:

1 >>> def func(a,b,c=0,*args,**kw):2 ... print 'a=',a,'b=',b,'c=',c,'args =',args,'kw =',kw3 ...4 >>> func(1,2)5 a= 1 b= 2 c= 0 args = () kw = {}

1 >>> func(1,2,c=3)2 a= 1 b= 2 c= 3 args = () kw ={}3 >>> func(1,2,3,'a','b')4 a= 1 b= 2 c= 3 args = ('a', 'b') kw ={}5 >>> func(1,2,3,'a','b',x = 45,y = 65,z = 32)6 a= 1 b= 2 c= 3 args = ('a', 'b') kw = {'y': 65, 'x': 45, 'z': 32}7 >>>

最神奇的是通过一个tuple和dict,你也可以调用该函数:

1 >>> args = (1, 2, 3, 4)2 >>> kw = {'x': 99}3 >>> func(*args, **kw)4 a = 1 b = 2 c = 3 args = (4,) kw = {'x': 99}

所以,对于任意函数,都可以通过类似func(*args, **kw)的形式调用它,无论它的参数是如何定义的。

python自定义函数的关键字_python学习之--自定义函数:相关推荐

  1. python巩固函数和模块_Python学习教程6:函数,模块和类的使用

    Python函数 定义 函数是组织好的,可重复利用的,用来实现单一,或相关联功能的代码片段. 函数能提高应用的模块行,使代码逻辑更加的条理清晰. 内建函数 内建函数是Python中自带的,可供用户重复 ...

  2. python语言中不用来定义函数的关键字_Python 语言中用来定义函数的关键字是

    Python 语言中用来定义函数的关键字是 答:def 调查问卷采集是数据采集人员通过设计具有针对性的问卷,采用方式进行信息采集 答:以上都是 中国大学MOOC: 突出重点,必须以解决问题为目标.也就 ...

  3. python中setup函数的用法_python学习之setUp函数和tearDown函数

    1,setUp():就是在一个类中最先被调用的函数,每次执行一个函数都要先执行这个函数,有几个函数就被调用几次,与放的位置无关,随便放到哪里都会先执行这个函数 2,tearDown():就是在一个类中 ...

  4. python 函数参数传递 格式_Python学习6.1_函数参数及参数传递

    大多数编程语言都绕不开一个名词,那就是--函数(function).而函数很重要的部分则是参数(arguments)的使用.Python的参数传递总体来说是根据位置,传递对应的参数.阐述如下: 1.位 ...

  5. python自定义函数复制字符串_Python学习笔记摘要(一)类型 字符串 函数 列表 深浅拷贝...

    python中的对象和类型 在python中,认为系统中的每一个"东西"都是一个对象,在python中,"对象"有着特殊的意义,python中的对象有: 一个标 ...

  6. python函数的作用域_python学习第五篇 函数 变量作用域

    原博文 2019-07-18 23:40 − 函数 函数是组合好的,可以重复使用的,用来实现单一或相关联功能的代码片段作用 能提高应用的模块性和代码的重复利用率函数的创建 第一函数的规则 1.函数代码 ...

  7. python第三方库中函数调用_Python学习笔记(2)——Python的函数、模块、包和库...

    初识Python,对于没有接触过编程的我,恐怕只能听懂什么是函数,这里介绍一下几个概念,并给出Python在调用方面的独特之处. 函数 理解为数学上的函数就可以了.下载安装完python后,并不是所有 ...

  8. python函数是一段具有特定功能的语句组_Python学习笔记(五)函数和代码复用

    本文将为您描述Python学习笔记(五)函数和代码复用,具体完成步骤: 函数能提高应用的模块性,和代码的重复利用率.在很多高级语言中,都可以使用函数实现多种功能.在之前的学习中,相信你已经知道Pyth ...

  9. 在python子程序中、使用关键字_Python 的控制和函数

    控制if else for while 函数 函数的定义 函数一词来源于数学,但编程中的函数概念,与数学中的函数是有很大不同的,具体区别,我们后面会讲,编程中的函数在英文中也有很多不同的叫法.在BAS ...

最新文章

  1. Flask上传文件到本地(底层方法实现)。
  2. Redis Zrevrangebyscore 命令
  3. C++modular exponentiation模幂运算的实现算法(附完整源码)
  4. vue搜索好友_Vue实现类似通讯录功能(中)
  5. mysql_ping与mysql长连接
  6. 内网渗透中SSh的巧用
  7. MaxCompute,基于Serverless的高可用大数据服务 1
  8. C语言源代码系列-管理系统之物业费管理
  9. usb, micro-usb card 损坏, 数据恢复
  10. 多个excel工作簿合并_你还在使用复制粘贴合并表格?一个公式搞定Excel多工作簿合并...
  11. matlab画正态分布图简单算法
  12. vue基于Echarts的拖拽数据可视化功能实现
  13. dying relu 和weight decay
  14. 使用python基于socket的tcp服务器聊天室
  15. 一文彻底弄清4G/蓝牙/WiFi/TCP/IP之间的关系
  16. Word文档怎么删除html标签,word怎么清除所有格式
  17. 自从用了低代码开发,开发效率提升10倍
  18. 位于本地计算机上 错误1068怎么办,错误1068怎么解决
  19. JAVA实现MD5带盐加密_MD5加盐加密
  20. 夜莺:2019年运营微信个人号的3个营销价值

热门文章

  1. cmake编译.a/.so/bin(一)
  2. wifi不断重连报错:eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON解决
  3. 主板开启网络唤醒(Wake on lan)
  4. 法兰克机器人外部自动_行业数据 | 服务机器人销售额创新纪录:全球增长32
  5. axios 上传文件_聚是一团火散作满天星,前端Vue.js+elementUI结合后端FastAPI实现大文件分片上传...
  6. linux shell脚本 可以全局使用
  7. MySQL中table_schema的基本操作
  8. c++ 等待子线程结束_进程和线程
  9. python一切皆对象的理解_Python难点解析---初级篇2.一切皆对象
  10. java expression 强制出现_Java中带有强制括号对的单行循环