Python练习:从入门到实践——函数

目录

一、定义函数

1.1 向函数传递信息

1.2 实参与形参

二、传递实参

2.1 位置实参

2.2  关键字实参

2.3 默认值

2.4 等效的函数调用

2.5 避免实参错误

三、返回值

3.1 返回简单值

3.2 实参可选

3.3 返回字典

三、 函数与while结合

四、传递列表

4.1 在函数中修改列表

4.2 禁止函数修改列表

练习

五、传递任意数量的实参

5.1 结合使用位置实参和任意数量实参

5.2 使用任意数量的关键字实参

六、将函数存储在模块中

6.1 导入整个模块

6.2 导入特定的函数

6.3 使用as给函数指定别名

6.4 使用as给模块指定别名

6.5 导入模块中的所有函数

七、函数编写指南


函数是带名字的代码块,用于完成具体的工作

一、定义函数

  • 使用关键字 def 定义一个函数 
  • 函数名 (参数1,参数2,参数3...)
  • 调用函数时,指定函数名及所需参数
# 定义函数
def greet_user():
    '''显示简单的问候语'''
    print("Hello!")

# 引用函数
greet_user()

1.1 向函数传递信息

def greet_user(username):
    """ 显示简单的问候语 """
    print("Hello, " + username.title() + "!")

greet_user('gina')

1.2 实参与形参

  • 在greet_user() 函数中,username 是一个形参,指示函数要完成其工作所需要的信息;
  • 调用函数时,'gina'为实参,实参是调用函数时传递给函数的信息

二、传递实参

定义函数时,一个函数可能包含多个形参,将实参与形参关联起来的方式有两种:

  • 位置实参,要求实参的顺序与形参相同
  • 关键字实参,每个实参都由变量名和值组成,还可以使用列表和字典

2.1 位置实参

e.g 显示宠物信息的函数,指出一个宠物属于哪种动物以及它叫什么名字。

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('cat','mona')

位置实参的顺序很重要!

2.2  关键字实参

关键字实参 传递给函数一对值,参数名=参数值,因此向函数传递实参是无需考虑函数调用中实参的顺序。

describe_pet(pet_name='doudou',animal_type='dog')

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

2.3 默认值

  • 编写函数时,可为每个形参指定默认值
  • 在调用函数时,若为形参指定了相应的实参值,Python将使用指定的实参值;否则将使用形参的默认值
  • 给形参指定默认值后,可在函数调用中省略相应的实参,因此使用默认值可简化函数调用
def describe_pet(pet_name,animal_type='dog'):
    """ 显示宠物信息 """
    print("\nI have a " + animal_type +".")
    print("My " + animal_type +"'s name is " + pet_name.title() + ".")

describe_pet('doudou')
describe_pet('pipi')

# 为函数提供显式的实参值 animal_type='cat',Python将忽略默认值
describe_pet('mona','cat')

使用默认值时,在形参列表中必须先列出没有默认值的形参,再列出有默认值的实参,使得Python可以正确地解读位置实参。

2.4 等效的函数调用

可以混合使用位置实参、关键字实参和默认值。

e.g 

def describe_pet(pet_name,animal_type='dog')
  • 基于此情况:
  • 必须给pet_name提供实参
  • 指定实参时,可以使用位置实参,也可以使用关键字实参
  • 如果描述的动物不是dog,必须在函数调用中给animal_type提供实参
describe_pet('doudou')
describe_pet(pet_name='doudou')

describe_pet('mona','cat')
describe_pet(pet_name='mona',animal_type='cat')
describe_pet(animal_type='cat',pet_name='mona')

只要保证函数的输出时正确的,使用哪种调用方式是无所谓的。

2.5 避免实参错误

保证提供的实参数量+默认值=形参数量

三、返回值

  • 可以使用函数处理一些数据并且获得一个或一组值,函数返回的值称为返回值
  • 使用return语句将值返回到调用函数的代码行

3.1 返回简单值

return 返回值

def get_formatted_name(first_name,last_name):
    full_name=first_name.title() + ' ' + last_name.title()
    return full_name

print(full_name('gina','li'))

3.2 实参可选

使用默认值将实参变成可选的。

def get_formatted_name(first_name,last_name,middle_name=''):
    if middle_name:
        full_name = first_name.title() +' ' + last_name.title()
    else:
        full_name = first_name.title() + ' ' + middle_name.title()\
                    + ' ' + last_name.title()
    return full_name

musician = get_formatted_name('jimi','hendix')
print(musician)

musician = get_formatted_name('john','hooker','lee')
print(musician)
  • Python将非空字符串解读为True
  • 换行符 \

3.3 返回字典

函数可返回任意类型的值,包括列表和字典等较复杂的数据结构。

def build_person(first_name, last_name):
    """" 返回字典,包含一个人的信息 """
    person = {'first': first_name,'last': last_name }
    return person

musician = build_person('jimi','hendrix')
print(musician)

扩展函数,接受可选值。

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',27)
print(musician)

三、 函数与while结合

e.g 使用姓和名与用户打招呼。

def get_formatted_name(first_name, last_name):
    full_name = first_name.title() + ' ' + last_name.title()
    return full_name

while True:
    print("\nPlease tell me your name:")
    print ("enter 'q' at any time to quit)" )
    f_name = input("First name: ")
    if f_name == 'q':
        break

    l_name = input("Last name:")
    if l_name == 'q':
        break

    formatted_name = get_formatted_name(f_name,l_name)
    print("\nHello, " + formatted_name + "!")

四、传递列表

e.g 向函数传递列表

def greet_users(names):
    for name in names:
        msg = "Hello, " + name.title() + "!"
        print(msg)

usernames = ['jay','juli','margot']
greet_users(usernames)

4.1 在函数中修改列表

在函数中对列表所做的任何修改都是永久性的。

e.g 

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_compledted_models(completed_models):
    print("\nThe following models have been printed:")
    for completed_modle in completed_models:
        print(completed_modle)

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

print_models(unprinted_designs,completed_modles)
show_compledted_models(completed_modles)

4.2 禁止函数修改列表

将列表的副本传递给函数。

切片表示 [:] 创建列表的副本。

function_name(list_name[:])

虽然向函数传递列表的副本可以保留原始列表的内容,但是除非特殊要求需要传递副本,否则还是应将原始列表传递给函数,因为使用现成的原始列表可以避免花时间和内存创建副本,从而提高效率,在处理大型列表是尤其如此。

练习

  1. 创建一个包含魔术师名字的列表,并将其传递给一个名为show_magicians()的函数,这个函数打印列表中每个魔术师的名字;
  2. 编写一个名为make_great()的函数,对魔术师列表进行修改,在每个魔术师的名字中都加入字样“the Great”,调用show_magicians(),确认魔术师列表确实变了;
  3. 在调用make_great()函数时,向其传递魔术师列表的副本,不修改原始列表;返回修改后的列表,并将其存储到另一个列表中,分别使用这两个列表来调用show_magicians(),确认一个列表包含原始魔术师的名字,另一个列表包含添加了 the great 字样的魔术师名字。
def show_magicians(magicians):
    for magician in magicians:
        print(magician.title())

def make_great(magicians):
    l = len(magicians)
    for i in range(l):
        magicians[i] = "the Great " + magicians[i]
    return magicians

magicians = ['liu qian','jay chou']

new_magicians = make_great(magicians[:])
show_magicians(magicians)
show_magicians(new_magicians)

五、传递任意数量的实参

解决问题:有时,预先不知道函数需要接受多少个实参

处理方式:*形参名

e.g  制作披萨的函数,预先无法确定加入多少配料。(该函数只有一个形参*toppings。)

def make_pizza(*toppings):
    print("\nMaking pizza with the following toppings:")
    for topping in toppings:
        print("-" + topping)

make_pizza('pepperoni')
make_pizza('mushroom','green peppers','extra cheese')
  • 不论函数收到几个实参,都能处理
  • 形参名*toppings中的“*”让python创建一个名为toppings的空元组,并将收到的所有值都封装到这个元组中

5.1 结合使用位置实参和任意数量实参

如果让函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后。Python先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。

# python将收到的第一个值存储在形参size中,将其他所有值都存储在元组toppings中。

def make_pizza(size,*toppings):
    print("\nMaking a " + str(size) +
          "-inch pizza with the following toppings:")
    for topping in toppings:
        print("-" + topping)

# 在函数调用中,首先指定表示比萨尺寸的实参,然后根据需要指定任意数量的配料。
make_pizza(12,'pepperoni')
make_pizza(16,'mushroom','green peppers','extra cheese')

5.2 使用任意数量的关键字实参

有时,需要接受任意数量的实参,但是预先不知道传递给函数的会是什么信息,

在这种情况下可将函数编写成可接受任意数量的“键—值对”——调用语句提供了多少就接受多少。

e.g 创建用户简介:你将收到有关用户的信息,但不确定会是什么样的信息。build_profile()接受名和姓,同时还接受任意数量的关键字实参。

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('albert','einstein',location='princeton',field='physics')
print(user_profile)
  • build_profile() 的定义要求用户必须提供姓和名,同时允许用户根据需要提供任意数量的“值对”;
  • 形参**user_info中两个星号让python创建一个名为user_info的空字典,并将收到的所有名称——值对,都封装到这个字典中;
  • 在这个函数中,可以像访问其他字典一样访问user_info中的键值对。

六、将函数存储在模块中

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

6.1 导入整个模块

模块是扩展名为.py的文件,包含要导入程序中的代码。

e.g 创建一个包含函数make_pizza() 的模块。

pizza.py

def make_pizza(size,*toppings):
    print("\nMaking a " + str(size) +
          "-inch pizza with the following toppings:")
    for topping in toppings:
        print("-" + topping)

在pizza.py所在的目录创建另一个名为making_pizza.py的文件,在这个文件中导入创建的模块pizza.py,并调用函数make_pizza()两次

import pizza
pizza.make_pizza(12,'pepperoni')
pizza.make_pizza(16,'mushroom','green peppers','extra cheese')

import pizza 让python打开文件pizza.py,并将其中的所有函数都复制到这个程序中,进而在making_pizza中可以使用pizza中定义的所有函数。

# 导入模块
import module_name

# 调用模块中的函数
module_name.function_name()

6.2 导入特定的函数

from module_name import function_name

使用逗号,分隔函数名,可根据需要从模块中导入任意数量的函数

from module_name import function_name0,function_name1,function_name2

使用这种语法调用函数时,无需使用句点。

6.3 使用as给函数指定别名

若要导入的函数名称与程序中现有的名称冲突,或函数名称太长,可以指定简短且独一无二的别名。

e.g 

from pizza import making_pizza as mp

mp(16,'pepperoni')

6.4 使用as给模块指定别名

import pizza as p
p.making_pizza(12,'pepperoni')

6.5 导入模块中的所有函数

使用运算符(*)导入模块中的所有函数

from module_name import *

七、函数编写指南

  • 应给函数指定描述性名称,且只在其中使用小写字母和下划线,为模块命名时也应遵循此规则,描述性名称可帮助别人明白代码的作用;
  • 每个函数都应包含简要的注释,注释紧跟在函数定义之后,(知道函数的名称、需要的实参、返回值的类型,就能在自己的程序中使用它)
  • 给形参指定默认值时,等号两边不要有空格
def function_name(parameter_0,parameter_1='default value')
  • 函数调用中的关键字实参,等号两边也不要有空格
function_name(value_0,parameter_1='value')
  • 如果程序或模块中包含多个函数,可使用两个空行将相邻的函数分割开,以便知道上一个函数何时结束,下一个函数何时开始
  • 所有的import语句都应放在文件开头

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值