《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循环结合起来使用。你还知道了如何将 函数存储在被称为模块的独立文件中,让程序文件更简单、更易于理解。后,你学习了函数编 写指南,遵循这些指南可让程序始终结构良好,并对你和其他人来说易于阅读。

你可能感兴趣的:(《Python编程从入门到实践》第八章)