Python 基础知识全篇-函数进阶

在上一节,我们了解了最基本的函数。这一节我们将要学习更多函数的特性。例如使用函数返回值,如何在不同的函数间传递不同的数据结构等。

参数缺省值

我们初次介绍函数的时候,用的是下述例子:

def thank_you(name):

    # This function prints a two-line personalized thank you message.

    print("\nYou are doing good work, %s!" % name)

    print("Thank you very much for your efforts on this project.")


thank_you('Adriana')

thank_you('Billy')

thank_you('Caroline')

上述代码中,函数都能正常工作。但是在不传入参数时,函数就会报错。如下所示:

def thank_you(name):

    # This function prints a two-line personalized thank you message.

    print("\nYou are doing good work, %s!" % name)

    print("Thank you very much for your efforts on this project.")


thank_you('Billy')

thank_you('Caroline')

thank_you()

出现这个错误是合乎情理的。函数需要一个参数来完成它的工作,没有这个参数就没办法工作。

这就引出了一个问题。有时候你想在不传参数的时候让函数执行默认的动作。你可以通过设置参数的缺省值实现这个功能。缺省值是在函数定义的时候确定的。如下所示:

def thank_you(name='everyone'):

    # This function prints a two-line personalized thank you message.

    #  If no name is passed in, it prints a general thank you message

    #  to everyone.

    print("\nYou are doing good work, %s!" % name)

    print("Thank you very much for your efforts on this project.")


thank_you('Billy')

thank_you('Caroline')

thank_you()

在函数中有多个参数,且其中一些参数的值基本不变时,使用参数缺省值是非常有帮助的。它可以帮助函数调用者只关注他们关心的参数。

动手试一试

Games

写下一个函数,接受一个参数,参数为一种游戏的名字。在函数内部打印一条语句,例如 "I like playing chess!"。

给参数一个缺省值。

调用至少 3 次你的函数。至少包含一次不带参数的调用。

# Ex : Games

# put your code here

位置参数

使用函数的很重要的一点就是如何向函数中传递参数。我们已经学到的都是最简单的参数传递,只有一个参数。接下来我们了解一下如何传递两个以上的参数。

我们创建一个包含 3 个参数的函数,包含一个人的名,姓和年纪。如下所示:

def describe_person(first_name, last_name, age):

    # This function takes in a person's first and last name,

    #  and their age.

    # It then prints this information out in a simple format.

    print("First name: %s" % first_name.title())

    print("Last name: %s" % last_name.title())

    print("Age: %d\n" % age)

describe_person('brian', 'kernighan', 71)

describe_person('ken', 'thompson', 70)

describe_person('adele', 'goldberg', 68)

在这个函数中,参数是 first_name , last_name , age 。它们被称为位置参数。Python 会根据参数的相对位置为它们赋值。在下面的调用语句中:

describe_person('brian', 'kernighan', 71)

我们给函数传递了 briankernighan71 三个值。Python 就会根据参数位置将 first_name 和 brian 匹配,last_name 和 kernighan 匹配,age 和 71 匹配。

这种参数传递方式是相当直观的,但是我们需要严格保证参数的相对位置。

如果我们混乱了参数的位置,就会得到一个无意义的结果或报错。如下所示:

def describe_person(first_name, last_name, age):

    # This function takes in a person's first and last name,

    #  and their age.

    # It then prints this information out in a simple format.

    print("First name: %s" % first_name.title())

    print("Last name: %s" % last_name.title())

    print("Age: %d\n" % age)

describe_person(71, 'brian', 'kernighan')

describe_person(70, 'ken', 'thompson')

describe_person(68, 'adele', 'goldberg')

这段代码中,first_name 和 71 匹配,然后调用 first_name.title() ,而整数是无法调用 title() 方法的。

关键字参数

Python 中允许使用关键字参数。所谓关键字参数就是在调用函数时,可以指定参数的名字给参数赋值。改写上述代码,示例如下:

def describe_person(first_name, last_name, age):

    # This function takes in a person's first and last name,

    #  and their age.

    # It then prints this information out in a simple format.

    print("First name: %s" % first_name.title())

    print("Last name: %s" % last_name.title())

    print("Age: %d\n" % age)

describe_person(age=71, first_name='brian', last_name='kernighan')

describe_person(age=70, first_name='ken', last_name='thompson')

describe_person(age=68, first_name='adele', last_name='goldberg')

这样就能工作了。Python 不再根据位置为参数赋值。而是通过参数名字匹配对应的参数值。这种写法可读性更高。

混合位置和关键字参数

有时候混合使用位置和关键字参数是有意义的。我们还是用上述例子,增添一个参数继续使用位置参数。如下所示:

def describe_person(first_name, last_name, age, favorite_language):

    # This function takes in a person's first and last name,

    #  their age, and their favorite language.

    # It then prints this information out in a simple format.

    print("First name: %s" % first_name.title())

    print("Last name: %s" % last_name.title())

    print("Age: %d" % age)

    print("Favorite language: %s\n" % favorite_language)

describe_person('brian', 'kernighan', 71, 'C')

describe_person('ken', 'thompson', 70, 'Go')

describe_person('adele', 'goldberg', 68, 'Smalltalk')

我们假设每个人调用这个函数的时候都会提供first_namelast_name。但可能不会提供其他信息。因此first_namelast_name使用位置参数,其他参数采用关键字参数的形式。如下所示:

def describe_person(first_name, last_name, age=None, favorite_language=None, died=None):

    """

    This function takes in a person's first and last name, their age,

    and their favorite language.

    It then prints this information out in a simple format.

    """


    print("First name: %s" % first_name.title())

    print("Last name: %s" % last_name.title())


    # Optional information:

    if age:

        print("Age: %d" % age)

    if favorite_language:

        print("Favorite language: %s" % favorite_language)

    if died:

        print("Died: %d" % died)

    # Blank line at end.

    print("\n")

describe_person('brian', 'kernighan', favorite_language='C')

describe_person('adele', 'goldberg', age=68, favorite_language='Smalltalk')

describe_person('dennis', 'ritchie', favorite_language='C', died=2011)

describe_person('guido', 'van rossum', favorite_language='Python')

动手试一试

Sports Teams

写下一个函数,接收两个参数。城市名和那个城市的球队名。

调用3次你的函数,混合使用位置和关键字参数。

# Ex : Sports Team

# put your code here

利用关键字参数我们可以灵活处理各种调用语句。然而,我们还有其他一些问题需要处理。我们考虑一个函数,接收两个数字参数,并打印数字之和。示例如下:

def adder(num_1, num_2):

    # This function adds two numbers together, and prints the sum.

    sum = num_1 + num_2

    print("The sum of your numbers is %d." % sum)


# Let's add some numbers.

adder(1, 2)

adder(-1, 2)

adder(1, -2)

这个函数运行良好。但是如果我们传入3个参数呢,看起来这种情况也应该是可以作算术运算的。如下所示:

def adder(num_1, num_2):

    # This function adds two numbers together, and prints the sum.

    sum = num_1 + num_2

    print("The sum of your numbers is %d." % sum)


# Let's add some numbers.

adder(1, 2, 3)

出乎意料,函数出错了。为什么呢?

这是因为无论采用什么形式的参数,函数只接受2个参数。事实上在这种情况下,函数只能恰好接受2个参数。怎么样才能解决参数个数问题呢?

接受任意长度的序列

Python 帮助我们解决了函数接受参数个数的问题。它提供了一种语法,可以让函数接受任意数量的参数。如果我们在参数列表的最后一个参数前加一个星号,这个参数就会收集调用语句的剩余参数并传入一个元组。(剩余参数是指匹配过位置参数后剩余的参数)示例如下:

def example_function(arg_1, arg_2, *arg_3):

    # Let's look at the argument values.

    print('\narg_1:', arg_1)

    print('arg_2:', arg_2)

    print('arg_3:', arg_3)


example_function(1, 2)

example_function(1, 2, 3)

example_function(1, 2, 3, 4)

example_function(1, 2, 3, 4, 5)

你也可以使用for循环来处理剩余参数。

def example_function(arg_1, arg_2, *arg_3):

    # Let's look at the argument values.

    print('\narg_1:', arg_1)

    print('arg_2:', arg_2)

    for value in arg_3:

        print('arg_3 value:', value)

example_function(1, 2)

example_function(1, 2, 3)

example_function(1, 2, 3, 4)

example_function(1, 2, 3, 4, 5)

我们现在就可以重写adder()函数,示例如下:

def adder(num_1, num_2, *nums):

    # This function adds the given numbers together,

    #  and prints the sum.


    # Start by adding the first two numbers, which

    #  will always be present.

    sum = num_1 + num_2


    # Then add any other numbers that were sent.

    for num in nums:

        sum = sum + num


    # Print the results.

    print("The sum of your numbers is %d." % sum)


# Let's add some numbers.

adder(1, 2)

adder(1, 2, 3)

adder(1, 2, 3, 4)

adder(1, 2, 3, 4, 5)

接受任意数量的关键字参数

Python 也提供了一种接受任意数量的关键字参数的语法。如下所示:

def example_function(arg_1, arg_2, **kwargs):

    # Let's look at the argument values.

    print('\narg_1:', arg_1)

    print('arg_2:', arg_2)

    print('arg_3:', kwargs)


example_function('a', 'b')

example_function('a', 'b', value_3='c')

example_function('a', 'b', value_3='c', value_4='d')

example_function('a', 'b', value_3='c', value_4='d', value_5='e')

上述代码中,最后一个参数前有两个星号,代表着收集调用语句中剩余的所有键值对参数。这个参数常被命名为kwargs。这些参数键值对被存储在一个字典中。我们可以循环字典取出参数值。如下所示:

def example_function(arg_1, arg_2, **kwargs):

    # Let's look at the argument values.

    print('\narg_1:', arg_1)

    print('arg_2:', arg_2)

    for key, value in kwargs.items():

        print('arg_3 value:', value)


example_function('a', 'b')

example_function('a', 'b', value_3='c')

example_function('a', 'b', value_3='c', value_4='d')

example_function('a', 'b', value_3='c', value_4='d', value_5='e')

def example_function(**kwargs):

    print(type(kwargs))

    for key, value in kwargs.items():

        print('{}:{}'.format(key, value))


example_function(first=1, second=2, third=3)

example_function(first=1, second=2, third=3, fourth=4)

example_function(name='Valerio', surname='Maggio')

此前我们创建过一个描述人的信息的函数。但是我们只能传递有限的信息,因为参数的个数在定义时已经被限制。现在利用刚刚学习的知识,我们可以传递任意数量任意形式的信息,如下所示:

def describe_person(first_name, last_name, **kwargs):

    # This function takes in a person's first and last name,

    #  and then an arbitrary number of keyword arguments.


    # Required information:

    print("First name: %s" % first_name.title())

    print("Last name: %s" % last_name.title())


    # Optional information:

    for key in kwargs:

        print("%s: %s" % (key.title(), kwargs[key]))


    # Blank line at end.

    print("\n")

describe_person('brian', 'kernighan', favorite_language='C')

describe_person('ken', 'thompson', age=70)

describe_person('adele', 'goldberg', age=68, favorite_language='Smalltalk')

describe_person('dennis', 'ritchie', favorite_language='C', died=2011)

describe_person('guido', 'van rossum', favorite_language='Python')

关于函数还有很多要学习的,但是综合以前已经学到的知识,你应该能根据你的需求写出简单,整洁的函数。自己动手试试吧!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343