第零章 学前准备
第一章 数据结构 – 基本数据类型
第一章 数据结构 – 字符串
第一章 数据结构 – 列表、元组和切片
第一章 数据结构 – 字典
第一章 数据结构 – 集合
第一章 – 数组、队列、枚举
第一章 数据结构 – 序列分类
第二章 控制流程
第三章 函数也是对象 – 函数定义以及参数
文章目录
第三章 函数也是对象 – 函数定义以及参数
3.1 函数定义语法
- 关键字
def
,表明定义一个函数; fib
,函数名;n
:函数参数(optional
);"""Print a Fibonacci series up to n.""":docstring
,对函数的解释(optional
);- 接下来是函数体,定义函数的全部操作;
- 函数体内如果需要返回值,那么需要使用return,没有的话,默认返回None(
optional
);
def fib(n): # write Fibonacci series up to n
"""Print a Fibonacci series up to n."""
result = []
a, b = 0, 1
while a < n:
result.append(a)
a, b = b, a+b
return result
# Now call the function we just defined:
print(fib(2000))
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597]
3.2 函数参数
3.2.1 实参和形参
在上面定义的函数中,参数 n
是形参(函数完成功能所需的一项数据), 2000
是实参(调用函数时传递给函数的信息)。
3.2.2 参数默认值
函数 ask_ok
中, retries
和 reminder
都给了默认值,那么调用的方式:
- 只给强制参数:
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!')
def ask_ok(prompt, retries=4, reminder='Please try again!'):
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 ValueError('invalid user response')
print(reminder)
3.2.2 从定位参数(Positional only)到仅限关键字参数(Keyword only)
3.2.2.1 定位参数和关键字参数
函数参数也可以以 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
, type
),那么函数可以以以下方式调用。
# valid ways
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
下面的方式不合理:
# invalid ways
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
所以,在函数调用中,关键词参数必须在定位参数之后,所有的关键词参数关键词必须和函数定义形参中的一个形参名一致,关键词参数的顺序没有要求。所有参数中,不可以重复传值。
3.2.2.2 **kwargs
和 *args
可变参数
当函数定义参数时,出现 **kwargs
(名字可以任意)时, kwargs
以一个字典保存了除明确定义的所有关键词参数。 *args
它以一个元组存储除它前面所有的位置参数。其中, *args
必须在 **kwargs
之前。
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)
for kw in keywords:
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")
def tag(name, *content, cls=None, **attrs):
"""生成一个或多个HTML标签"""
if cls is not None:
attrs['class'] = cls
if attrs:
attr_str = ''.join('%s="%s" ' % (attr, value)
for attr, value in sorted(attrs.items()))
else:
attr_str = ''
if content:
return '\n'.join('<%s %s>%s</%s>' % (name, attr_str, c, name) for c in content)
else:
return '<%s %s/>' % (name, attr_str)
print("-" * 40)
print("tag('br)", '\n', tag('br'), end=f"\n{'-'*40}\n")
print("tag('p', 'hello')", '\n', tag('p', 'hello'), end=f"\n{'-'*40}\n")
print("tag('p', 'hello', 'world')", '\n', tag(
'p', 'hello', 'world'), end=f"\n{'-'*40}\n")
print("tag('p', 'hello', id=33)", '\n', tag(
'p', 'hello', id=33), end=f"\n{'-'*40}\n")
print("tag('p', 'hello', 'world', cls='sidebar')", '\n', tag(
'p', 'hello', 'world', cls='sidebar'), end=f"\n{'-'*40}\n")
print("tag(content='testing', name='img')", '\n', tag(
content='testing', name="img"), end=f"\n{'-'*40}\n")
my_tag = {'name': 'img', 'title': 'Sunset Boulevard',
'src': 'sunset.jpg', 'cls': 'framed'}
print("tag(**my_tag)", '\n', tag(**my_tag), end=f"\n{'-'*40}\n")
-- 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.
----------------------------------------
shopkeeper : Michael Palin
client : John Cleese
sketch : Cheese Shop Sketch
----------------------------------------
tag('br)
<br />
----------------------------------------
tag('p', 'hello')
<p >hello</p>
----------------------------------------
tag('p', 'hello', 'world')
<p >hello</p>
<p >world</p>
----------------------------------------
tag('p', 'hello', id=33)
<p id="33" >hello</p>
----------------------------------------
tag('p', 'hello', 'world', cls='sidebar')
<p class="sidebar" >hello</p>
<p class="sidebar" >world</p>
----------------------------------------
tag(content='testing', name='img')
<img content="testing" />
----------------------------------------
tag(**my_tag)
<img class="framed" src="sunset.jpg" title="Sunset Boulevard" />
----------------------------------------