第三章 函数也是对象 -- 函数定义以及参数

第零章 学前准备
第一章 数据结构 – 基本数据类型
第一章 数据结构 – 字符串
第一章 数据结构 – 列表、元组和切片
第一章 数据结构 – 字典
第一章 数据结构 – 集合
第一章 – 数组、队列、枚举
第一章 数据结构 – 序列分类
第二章 控制流程
第三章 函数也是对象 – 函数定义以及参数


第三章 函数也是对象 – 函数定义以及参数

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 中, retriesreminder 都给了默认值,那么调用的方式:

  1. 只给强制参数:ask_ok('Do you really want to quit?')
  2. 给定一个可选参数(有默认值的参数也叫可选参数):ask_ok('OK to overwrite the file?', 2)
  3. 给定所有参数: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 ,以及三个可选参数( stateactiontype ),那么函数可以以以下方式调用。

# 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" />
----------------------------------------
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值