Python3 官方文档翻译 - 4.7 函数定义
4.7.1 默认函数定义
最常用的就是为一个或多个参数设定默认值,这让函数可以用比定义时更少的参数来调用,例如:
def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
while True:
ok = input(prompt)
if ok in ('y', 'ye', 'yes'):
return True
if ok in ('n', 'no', 'nop', 'nope'):
return False
retries = retries - 1
if retries < 0:
raise OSError('uncooperative user')
print(complaint)
可以通过下面几种方式调用:
- 给定一个必须参数:ask_ok('Do you really want to quit?')
- 给出一个可选参数:ask_ok('OK to overwrite the file?', 2)
- 或是给出全部参数:ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no!')
这个例子同样给出了 in 关键字,即测试一个元组里是否包含给定值。
默认值在 方法定义时 被赋值
i = 5 def f(arg=i):
print(arg) i = 6
f()
所以将会打印 5,因为 i 在方法定义时值为5
注意 ! 默认值只会被赋值一次,所以当默认值是一个可变对象例如List、Dict或多数类时会有不同,这个方法似乎每次总是记住了前一次调用的结果
def f(a, L=[]):
L.append(a)
return L print(f(1))
print(f(2))
print(f(3))
将会打印
[1]
[1, 2]
[1, 2, 3]
如果你不想让默认参数被后续的调用共享,可以这样定义,无论调多少次都不会有问题。
def f(a, L=None):
if L is None:
L = []
L.append(a)
return L
4.7.2 关键字参数
函数同样可以通过 'kwarg=value' 这样的关键字参数形式来调用,如下:
def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
print("-- This parrot wouldn't", action, end=' ')
print("if you put", voltage, "volts through it.")
print("-- Lovely plumage, the", type)
print("-- It's", state, "!")
这个函数只接受一个必须的参数(voltage),和三个可选参数(state, action, and type),可以通过下面任意方式调用:
parrot(1000) # 1 positional argument
parrot(voltage=1000) # 1 keyword argument
parrot(voltage=1000000, action='VOOOOOM') # 2 keyword arguments
parrot(action='VOOOOOM', voltage=1000000) # 2 keyword arguments
parrot('a million', 'bereft of life', 'jump') # 3 positional arguments
parrot('a thousand', state='pushing up the daisies') # 1 positional, 1 keyword
但下面的调用是不通过的:
parrot() # required argument missing
parrot(voltage=5.0, 'dead') # non-keyword argument after a keyword argument
parrot(110, voltage=220) # duplicate value for the same argument
parrot(actor='John Cleese') # unknown keyword argument
在一次函数调用中,关键字参数必须跟在位置参数后面。所有传入的关键字参数必须符合方法能接收的参数(例如parrot方法就不接受actor参数),而顺序并不重要,这当然也包括了必须的参数(比如parrot(voltage=1000)就是通过的)。没有参数可以被第二次接受,所以下面的示例是错误的:
>>> def function(a):
... pass
...
>>> function(0, a=0)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: function() got multiple values for keyword argument 'a'
当最后一个参数以 **name 的形式出现,这表示接收一个包含了所有关键字参数的Dictionary字典(看这里介绍)。它还可以结合一个 *name 形式的参数来调用,即接收一个可选参数的元组,注意*name 需出现在 **name 之前。
def cheeseshop(kind, *arguments, **keywords):
print("-- Do you have any", kind, "?")
print("-- I'm sorry, we're all out of", kind)
for arg in arguments:
print(arg)
print("-" * 40)
keys = sorted(keywords.keys())
for kw in keys:
print(kw, ":", keywords[kw])
可以这样调用:
cheeseshop("Limburger", "It's very runny, sir.",
"It's really very, VERY runny, sir.",
shopkeeper="Michael Palin",
client="John Cleese",
sketch="Cheese Shop Sketch")
打印出来这样:
-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
client : John Cleese
shopkeeper : Michael Palin
sketch : Cheese Shop Sketch
值得注意的是,打印出来的关键字参数是通过代码中的 sorted() 方法来排序的,因为Dictionary字典的keys 是无序的,如果不这样做打印出来的参数就是无序的
4.7.3 可变参数
最少使用的是指定函数可以传入可变参数来调用,这些参数被包装在tuple元组中(元组的概念)。
def write_multiple_items(file, separator, *args):
file.write(separator.join(args))
通常这些可变参数出现在形参的最后一个,因为它们会一股脑儿地把所有剩下的参数都传入方法。而任何出现在 *args 可变参数之后的形参必须是关键字参数(‘keyword-only’ arguments),确保它们只能被用作关键字参数而不会被当做可变参数。
>>> def concat(*args, sep="/"):
... return sep.join(args)
...
>>> concat("earth", "mars", "venus")
'earth/mars/venus'
>>> concat("earth", "mars", "venus", sep=".")
'earth.mars.venus'
4.7.4 使用 * 拆分参数列表
相反的情况发生在当参数已经组成一个tuple元组或是list列表却需要拆分成方法所需要的单独的位置参数。例如内置的 range() 方法接收单独的 start 和 stop 两个参数,如果手头只有list或tuple,我们可以用 * 操作符来把list或tuple拆分成关键字。
>>> list(range(3, 6)) # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> list(range(*args)) # call with arguments unpacked from a list
[3, 4, 5]
同样的,Dictionary字典也可用 ** 操作符拆分成关键字
>>> def parrot(voltage, state='a stiff', action='voom'):
... print("-- This parrot wouldn't", action, end=' ')
... print("if you put", voltage, "volts through it.", end=' ')
... print("E's", state, "!")
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !
4.7.5 Lambda表达式
通过Lambda关键字,你可以创建一些简短的匿名function。这个function就返回两个参数之和: lambda a, b: a+b 。Lambda表达式精炼地将function限制在一个表达式中,可以在任何地方替代function object来使用,从语法上来说其实就是Python中常规方法的"语法糖"。与嵌套方法定义相似,lambda表达式能够引用位于function范围内的变量。
>>> def make_incrementor(n):
... return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43
上面的例子使用Lambda function来返回一个方法,下面的例子是传入Lambda function来代替参数
>>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
>>> pairs.sort(key=lambda pair: pair[1])
>>> pairs
[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
4.7.6 文档字符串(Documentation Strings)
对于Doc strings,有一些约定是需要我们去遵守的。
第一行应当是对于方法目的简短且精确的概括。简要来说,既然方法的名称和返回类型可以通过其他方法获得,那么就不用再次明确地说明。
第一行应当以一个大写字母开头,以一个句号结尾。
如果有多行,那么第二行应为空,看起来像是把概括和剩下的描述部分分开。
剩下的行数则是用一行至多行来描述对象的调用规则、副作用等。
Python解释器并不会去除多行文本中的缩进,所以处理Doc strings的工具得自己去做,一般通过下面的约定来完成。
跟在文档第一行后面的第一个非空的行 A 决定了整个文档的缩进列数(我们不使用第一行作为参考是因为它通常是紧靠在文档的三个单引号'''后面,因此看起来并不明显)。相当于缩进长度的空格就被添加在所有行的前部。比 A 缩进列数更少的行不应该出现,但如果出现了,每一行前面所有的空格都会被移除。一个Tab缩进通常相当于8个空格。看下面的代码就很清楚:
>>> def my_function():
... '''Do nothing.
...
... No,really,it doesn't do anything.
... '''
... pass
...
>>> print(my_function.__doc__)
Do nothing. No,really,it doesn't do anything. >>> def less_or_more_indentation_func():
... '''Do something.
...
... second line,normal line
... less indentation line
... more indentation line
... '''
... pass
...
>>> print(less_or_more_indentation_func.__doc__)
Do something. second line,normal line
less indentation line
more indentation line
Python3 官方文档翻译 - 4.7 函数定义的更多相关文章
- cocos2dx 关于lua 绑定的环境配置官方文档翻译与 将自己定义c++方法绑定到lua的的方法
网上有好多写如何讲自己定义的方法绑定到lua的文章,当中都仅仅对环境配置做了简单的介绍,看到有的帖子写在绑定中遇到了各种各样的error.大部分是因为环境配置不对导致的,下面是官方的文档有标准的说明, ...
- Python3 官方文档翻译 - 5 数据结构
这章会更详细地描述了一些你已经学过的知识,同时添加一些新东西. 5.1 List进阶 下面是关于List的所有方法 list.append(x) 将元素添加至列表尾,相当于a[len(a):] = [ ...
- Python3.x:函数定义
Python3.x:函数定义 1,函数定义: def 函数名称([参数1,参数2,参数3......]): 执行语句 2,实例一(不带参数和没返回值): def helloWorld(): print ...
- Python3.2官方文档翻译--实例对象和方法对象
6.3.3 实例对象 如今我们用实例对象做什么呢?实例对象唯一可用的操作就是属性引用.如今有两种合法的属性名称:数据属性和方法. 数据属性相当于smallTalk中的实例变量,C++中的数据成员.数据 ...
- python3 参数*args 、 **args 在函数定义和调用中的应用
一.函数调用时 说明:*args 表示解包(解包 列表.元组.字符串类型) #定义函数cn_musql def cn_musql(host,port,user,pwd,db): print(host) ...
- Django 2.0.1 官方文档翻译: 编写你的第一个 Django app,第一部分(Page 6)
编写你的第一个 Django app,第一部分(Page 6)转载请注明链接地址 Django 2.0.1 官方文档翻译: Django 2.0.1.dev20171223092829 documen ...
- 基本控件文档-UITextField属性---iOS-Apple苹果官方文档翻译
本系列所有开发文档翻译链接地址:iOS7开发-Apple苹果iPhone开发Xcode官方文档翻译PDF下载地址 //转载请注明出处--本文永久链接:http://www.cnblogs.com/Ch ...
- 多线程---iOS-Apple苹果官方文档翻译
本系列所有开发文档翻译链接地址:iOS7开发-Apple苹果iPhone开发Xcode官方文档翻译PDF下载地址(2013年12月29日更新版) 多线程 技术博客http://www.cnblo ...
- kong插件官方文档翻译
kong插件官方文档翻译 目录 介绍 文件结构 编写自定义逻辑 存储配置 访问数据存储 自定义实体 缓存自定义实体 扩展Admin API 编写测试 (卸载)安装你的插件 插件开发 - 介绍 什么是插 ...
随机推荐
- 有关UIWebView的SSL总结
在网上找了非常多文章差点儿相同都是一样的,基本上都是关于NSURLConnection的文章. 如今把几个比較好的连接分享给大家http://blog.csdn.net/pingchangtan367 ...
- 远程登录阿里云上的MySQL
近期对云和server之类的感兴趣,想要将自己的数据什么的保存到远端server.研究了阿里云和百度云.今天算是有点进步吧. 我在阿里云上申请了个免费的云server(ECS),非常可惜仅仅能用5天. ...
- EBS OAF 开发中的OAMessageRadioGroup控件
EBS OAF 开发中的OAMessageRadioGroup控件 (版权声明,本人原创或者翻译的文章如需转载,如转载用于个人学习,请注明出处:否则请与本人联系,违者必究) 简单介绍 RadioGro ...
- 如何分割(split)string字符串
使用String#split()方法 如下所示: String string = "004-034556"; String[] parts = string.split(" ...
- java 无法割符日期字符串转yyyy-MM-dd hh:mm:ss
1.需要转换字符串(20150210125942),转化后要达到的目的:2015-02-10 12:59:42 public static void main(String[] args) { Str ...
- 使用RUBY生成二维码
二维码现在貌似已经成为一个项目必不可少的总分了,最近在做的微信项目,更是大大的依赖于二维码,微信公众平台提供的临时二维码,局限太多,只能带一个ID,做不了太多有意义的整个,因为我们很多的二维码是需要自 ...
- 1_HelloWorld
学iOS开发与学Swift是两件事情,Swift只是一种语言,它有官方手册,里面包含了全部的语法.对其他任何一门语言很熟悉的人,学习Swift可能只需要几天的时间.而这之后,学习iOS开发才是难点,有 ...
- Android系统设置— android.provider.Settings
android.provider.Settings Intent intent = new Intent(android.provider.Settings.ACTION_SETTINGS); sta ...
- 试用阿里云RDS的MySQL压缩存储引擎TokuDB
以前就用过自己搭建MySQL服务器的两种存储引擎MyISAM和InnoDB(也用过一点Memory方式),在今年初转向阿里云关系型数据库服务RDS的时候,看到可调参数中有一个TokuDB,不过不太了解 ...
- Java Date 和 Calendar
Java 语言的Date(日期),Calendar(日历),DateFormat(日期格式)组成了Java标准的一个基本但是非常重要的部分.日期是商业逻辑计算一个关键的部分,所有的开发者都应该能够计算 ...