【循序渐进学Python】6.Python中的函数

1. 创建函数

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

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

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

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

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

 

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

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

 

2. 文档字符串

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

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

 

3. 参数

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

 

3.1 不可变类型参数

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

 1 # 字符串是不可变的
 2 def try_to_change(n):
 3     n = 'Gumby'
 4 
 5 name = 'Sunshine'
 6 
 7 # 尝试改变参数的值
 8 try_to_change(name)
 9 
10 # output: Sunshine(函数内部的改变对其没有影响)
11 print name

 

3.2 可变类型参数

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

 1 # 列表是可变的
 2 def try_to_change2(n):
 3     n[0] = 'Sunshine'
 4 
 5 person = ['Gumby','Bob']
 6 # 尝试改变参数的值
 7 try_to_change2(person)
 8 
 9 # output: ['Sunshine', 'Bob']
10 # 函数内部的改变会作用于外部的变量
11 print person

 

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

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

 

3.3 关键字参数和默认值

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

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

1 def hello(gretting,name):
2     print "%s,%s!" % (gretting,name)
3 
4 # output: hello,world!
5 hello(name='world',gretting='hello')

 

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

1 def hello(gretting = 'hello',name='world'):
2     print "%s,%s!" % (gretting,name)
3 
4 hello() # hello,world!
5 hello(name = 'Sunshine') # hello,Sunshine!
6 hello('Greetings') # Greetings,world!

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

 

3.4 使用任意参数列表

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

 1 def print_params(number,*params):
 2     print number
 3     print params
 4 
 5 # output: 
 6 # 6
 7 # (1, 2, 3, 4, 5, 6)
 8 print_params(6,1,2,3,4,5,6)
 9 
10 # output:
11 # 0
12 # ()
13 print_params(0)

 

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

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

 

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

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

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

 

3.5 解包参数列表

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

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

 

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

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

 

参考资料&进一步阅读

Python基础教程(第二版)

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

转载于:https://www.cnblogs.com/IPrograming/p/Python_function.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/273956.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

求子数组的最大和

穷举法&#xff1a; int MaxSubArraySum(int a[], int n) { int i, j, MaxSum 0, tmpSum, cnt; for (i1; i<n; i) { for (j0; ji<n; j) { cnt 0; tmpSum 0; while (cnt < i) { tmpSum a[jcnt]; cnt; } if (MaxSum < tmpSum) { MaxSum tmpSum; } } } return Ma…

scrapy框架-post使用

scrapy中使用FormRequest向网页提交数据 Scrapy post使用 如何post data&#xff1a; http://httpbin.org/post FormRequest : post请求 GitHub Login 借助浏览器分析登陆行为。 分析post的内容先尝试一次错误的登陆&#xff1a;如下&#xff1a;分析&#xff1a;需要post…

duilib进阶教程 -- 改进窗口拖动 (12)

现在大家应该都知道caption"0,0,0,32"&#xff0c;是指示标题栏区了吧&#xff0c;如果想要整个窗口都能拖动呢&#xff1f; 那直接把高度改成和窗口一样不就得了~O(∩_∩)O~ 嗯&#xff0c;这样是可以&#xff0c;比如窗口高度是600&#xff0c;那么我们指定caption…

python- 基础 range方法的使用

1、第一种用法 index[1,2,0,5,9,8,10,6,4,7] for i in range(len(index)): print(index[i]) 结果&#xff1a; λ py test.py 1 2 0 5 9 8 10 6 4 7 2、第二种用法&#xff1a; index[1,2,0,5,9,8,10,6,4,7] for i in range(0,len(index),2): print(index[i]) 运…

Oracle行列转换小结

目录结构如下&#xff1a;行转列列转行[一]、行转列 1.1、初始测试数据 表结构&#xff1a;TEST_TB_GRADE Sql代码 create table TEST_TB_GRADE ( ID NUMBER(10) not null, USER_NAME VARCHAR2(20 CHAR), COURSE VARCHAR2(20 CHAR), SCORE FLOAT ) 初始…

python- 进阶 与flask的搭配使用---定时任务框架APScheduler学习详解

APScheduler简介 在平常的工作中几乎有一半的功能模块都需要定时任务来推动&#xff0c;例如项目中有一个定时统计程序&#xff0c;定时爬出网站的URL程序&#xff0c;定时检测钓鱼网站的程序等等&#xff0c;都涉及到了关于定时任务的问题&#xff0c;第一时间想到的是利用ti…

Mingw下g++编译执行顺序错误

今天写一个简单的线性表时&#xff0c;用Mingw中的g编译、调试、运行时发现一个奇怪的现象&#xff1a;程序的执行顺序与实际编写顺序不一致。 编译环境&#xff1a;代码编写 win7下 editplus Mingw 4.3.3 g 代码片段如下&#xff1a; 1 //function: create a list 2 //ti…

python系统学习1-程序设计的基本方法

一、程序设计基本方法 计算机与程序设计 编译和解释 程序的基本编写方法 计算机编程 1、计算机与程序设计 &#xff08;1&#xff09;、计算机是根据指令操作数据的设备 功能性&#xff1a;对数据的操作、表现为数据计算、输出输入处理和结果存储。 可编程性&#xff1a;…

python 系统学习实例1.1 - 华氏度与摄氏度的转换

# C ( F - 32 ) / 1.8‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬ # F C * 1.8 32‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫…

EMS问题

如果EMS启动后在运行时报出 JMS error: "Not allowed to create destination这个错误&#xff0c;可能就是你启动方式的问题了进入到EMS的安装目录的bin目录下&#xff0c;运行tibemsca.bat那个文件就好使了。转载于:https://www.cnblogs.com/xiaotianyu/p/3421737.html

python 系统学习实例1.2 - 人民币与美元的转换

# RMB USD / 6.78‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬ # USD RMB* 6.78 def tempConvert(): t input("请输入数值:") …

HDTV(1920x1080)码率和视频质量关系的研究 2 (实验结果)

上一篇文章中介绍了实验的准备工作&#xff0c; HDTV&#xff08;1920x1080&#xff09;码率和视频质量关系的研究 1 &#xff08;前期准备&#xff09; 本文介绍一下实验的结果。 首先来看一下主观评价的试验结果&#xff1a; 从实验结果来看&#xff0c;可以得出以下结论&…

python爬虫--如何爬取翻页url不变的网站

参考 https://blog.csdn.net/c350577169/article/details/80410133

POJ 1745 Divisibility DP

POJ:http://poj.org/problem?id1745 A完这题去买福鼎肉片&#xff0c;和舍友去买滴~舍友感慨“这一天可以卖好几百份&#xff0c;每份就算赚一块钱。。那么一个月。。一年。。。” 我说“那我们以后去卖这个吧&#xff0c;饿了还能自己煮着吃” 哈哈&#xff0c;一群天真的少…

NGUI如何创建自己的精灵图集

说实话其实很简单,但是在不知道的情况下真的不好弄啊. 1. 选择你要制作精灵图集的图片,可以选择多张 2. 提倡使用快捷键Alt Shift M 会有如下窗口弹出,也可以NGUI --> Open-->Atlas Maker打开 我们看到在Sprites里面就是我们选择的要制作图集的图片 当在Replace后面的输…

C++ - 进阶 1002

This time, you are supposed to find AB where A and B are two polynomials. Input Specification: Each input file contains one test case. Each case occupies 2 lines, and each line contains the information of a polynomial: K N​1​​ a​N​1​​​​ N​2​​…

修改6S Fortran77 代码,建立查找表

逐像元大气校正&#xff0c;常预先计算查找表&#xff08;LUT&#xff0c;LookUp Tabel&#xff09;&#xff0c;6S大气辐射传输模式也可以用来计算LUT。但6S源程序输出信息多&#xff0c;且浮点数输出精度低&#xff0c;不利于提取关键信息生成LUT&#xff0c;本文描述了怎样修…

c++ 实例

#include "stdafx.h" #include <iostream> using namespace std; int main() { int a; a 4; cout<<a<<endl; return 0; }

VMware虚拟机与宿主无法复制的解决办法

由于工作需要&#xff0c;上网机器使用虚拟机&#xff0c;因此需要经常来回的拷贝文件&#xff0c;而vmware从6.5一直走来到10.0.1&#xff0c;总是有一个问题很让人苦恼---共享粘贴板总是会无故失效。经常实验&#xff0c;发现可以经过以下方法临时解决一下&#xff0c;虽然不…

c++ pat 乙级 --1001 害死人不偿命的(3n+1)猜想

1001 害死人不偿命的(3n1)猜想 &#xff08;15 分&#xff09; 卡拉兹(Callatz)猜想&#xff1a; 对任何一个正整数 n&#xff0c;如果它是偶数&#xff0c;那么把它砍掉一半&#xff1b;如果它是奇数&#xff0c;那么把 (3n1) 砍掉一半。这样一直反复砍下去&#xff0c;最后…