《Python编程从入门到实践》第八章

定义函数

一个简单的例子:

def greet_user(username):
    print("Hello! " + username.title() + "!")
greet_user('jesse')

可在函数定义def greet_user()的括号内添加username。通过在这里添加username, 就可让函数接受你给username指定的任何值。代码greet_user('jesse')调用函数greet_user(),并向它提供执行print语句所需的信息。
变量username是一个形参---函数完成其工作所需的一项信息。而'jesse'是一个实参,实参是调用函数时传递给函数的信息。调用函数时,将要让函数使用的信息放在括号内。在greet_user('jesse')中,将实参 'jesse'传递给了函数greet_user(),这个值被存储在形参username中。

传递实参

鉴于函数定义中可能包含多个形参,因此函数调用中也可能包含多个实参。向函数传递实参 的方式很多,可使用位置实参,这要求实参的顺序与形参的顺序相同;也可使用关键字实参,其 中每个实参都由变量名和值组成;还可使用列表和字典。

位置实参

简单的关联方式是基于实参的顺序。这种关联方式被称为位置实参。 即按函数提供的形参顺序,提供实参。
一个例子:

def describe_pet(animal_type, pet_name):
    print("\nI have a " + animal_type + ".")
    print("My " + animal_type + "'s name is " + pet_name.title() + ".")

describe_pet('dog', 'Mike')
describe_pet('Mike', 'dog')#顺序错误,结果不同

关键字实参

关键字实参是传递给函数的名称—值对。直接在实参中将名称和值关联起来了,因此向函 数传递实参时不会混淆:
describe_pet(pet_name = "Mike", animal_type = "dog")

使用关键字实参时,务必准确地指定函数定义中的形参名

默认值

编写函数时,可给每个形参指定默认值。在调用函数中给形参提供了实参时,Python将使用 指定的实参值;否则,将使用形参的默认值。

def describe_pet(pet_name, animal_type = 'dog'):
    '''blablablablabla''' 
describe_pet(pet_name='Mike')
describe_pet('John', 'cat')

使用默认值时,在形参列表中必须先列出没有默认值的形参,再列出有默认值的形参。即带有默认值的形参应该放在参数列表最后。 这让Python依然能够正确地解读位置实参。

返回值

在函数中,使用return语句将值返回到调用函数的代码行。。返回值让你能 够将程序的大部分繁重工作移到函数中去完成,从而简化主程序。
一个例子:

def get_formatted_name(first_name, last_name, middle_name=''):
    if middle_name:
        full_name = first_name + ' ' + middle_name + ' ' + last_name
    else:
        full_name = first_name + ' ' + last_name
    return full_name.title()
musician = get_formatted_name('jimi', 'hendrix')
print(musician)

上例中,检查是否提供中间名,python将非空字符解读为True,将空字符解读为False。返回值还可以返回列表、字典等类型。
例如:

def build_person(first_name, last_name, age=''):
    person = {'first': first_name, 'last': last_name}
    if age:
        person['age'] = age
    return person
musician = build_person('jimi', 'hendrix', age=27)

传递列表

一个例子:

def greet_users(names):
    for name in names:
        msg = "Hello, " + name.title() + "!"
        print(msg)
usernames = ['hannah', 'try', 'margot']
greet_users(usernames)

将列表传递给函数后,函数就可对其进行修改。在函数中对这个列表所做的任何修改都是永 久性的,这让你能够高效地处理大量的数据。

def print_models(unprinted_designs, completed_models):
    while unprinted_designs:
        current_design = unprinted_designs.pop()
        print("Printing model: " + current_design) 
        completed_models.append(current_design)

def show_completed_models(completed_models):
    print("\nThe following models have been printed:")
    for completed_model in completed_models:
        print(completed_model)

unprinted_designs = ['iphone case', 'robot pendant', 'dodecahedron']
completed_models=[]

print_models(unprinted_designs, completed_models)
show_completed_models(completed_models)

尽量使每个函数都应只负责一项具体的工作。
为了避免在函数中修改原列表,可向函数传递列表的副本而不是原件;这样函数所做的任何修改都只影响副本,而丝毫不影响原件。
function_name(list_name[:])
虽然向函数传递列表的副本可保留原始列表的内容,但除非有充分的理由需要传递副本,否则还是应该将原始列表传递给函数,因为让函数使用现成列表可避免花时间和内存创建副本,从而提高效率,在处理大型列表时尤其如此。

传递任意数量的实参

一个例子:

def make_pizza(size, *toppings):
    print("\nMaking a " + str(size) + "-inch pizza with the following toppings: ")
    for topping in toppings:
        print("- " + topping)
make_pizza('pepperoni')
make_pizza('mushrooms', 'green peppers', 'extra cheese')

如果要让函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在后。Python先匹配位置实参和关键字实参,再将余下的实参都收集到后一个形参中。
形参名*toppings中的星号让Python创建一个名为toppings的空元组,并将收到的所有值都封 装到这个元组中。

有时候,需要接受任意数量的实参,但预先不知道传递给函数的会是什么样的信息。在这种情况下,可将函数编写成能够接受任意数量的键—值对——调用语句提供了多少就接受多少。
一个例子:

def build_profile(first, last, **user_info):
    profile = {}
    profile['first_name'] = first
    profile['last_name'] = last
    for key, value in user_info.items():
        profile[key] = value
    return profile
user_profile = build_profile('alber', 'einstein', location='princeton', field='physics')
print(user_profile)

形参**user_info中的两个星号让Python创建一个名为user_info的空字典,并将收到的所 有名称—值对都封装到这个字典中。

将函数存储在模块中

函数的优点之一是,使用它们可将代码块与主程序分离。通过给函数指定描述性名称,可让 主程序容易理解得多。将函数存储在被称为模块的独立文件中,再将模块导 入到主程序中。其中,需要将要导入的模块与程序放在同一个文件夹中。import语句允许在当前运行的程序文件中使用模块中的代码。

  1. 通过 import module_name 来导入模块,通过module_name.function_name()来调用模块中的函数。
  2. 通过 from module_name import function_name0,function_name1...来从模块中导入指定的函数,可以直接通过function_name0来调用。
  3. 如果要导入的函数的名称可能与程序中现有的名称冲突,或者函数的名称太长,可指定简短 而独一无二的别名——函数的另一个名称,类似于外号。如from module_name import function_name as fn
  4. 给模块起别名,import module_name as m
  5. 从模块中导入全部函数,from module_name import *,。由于导入 了每个函数,可通过名称来调用每个函数,而无需使用句点表示法。然而,使用并非自己编写的 大型模块时,好不要采用这种导入方法:如果模块中有函数的名称与你的项目中使用的名称相 同,可能导致意想不到的结果:Python可能遇到多个名称相同的函数或变量,进而覆盖函数,而不是分别导入所有的函数。

对于自己的函数,可以加入 '''注释''' 的方法便于理解,同时可以在console中通过function_name.doc的方式查看自己留下的注释,或者查看其他人函数中的注释。

在本章中,你学习了:如何编写函数,以及如何传递实参,让函数能够访问完成其工作所需 的信息;如何使用位置实参和关键字实参,以及如何接受任意数量的实参;显示输出的函数和返 回值的函数;如何将函数同列表、字典、if语句和while循环结合起来使用。你还知道了如何将 函数存储在被称为模块的独立文件中,让程序文件更简单、更易于理解。后,你学习了函数编 写指南,遵循这些指南可让程序始终结构良好,并对你和其他人来说易于阅读。

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

推荐阅读更多精彩内容