Python学习笔记(七)——函数

与C语言,C++一样,Python中函数也是非常重要的一部分。对于一项操作,我们有时不需要一遍遍反复编写执行代码,我们只要调用一个函数就够了。

一 定义函数

def great_user():
    """"打一个简单的招呼"""
    print("Hello")

great_user()

Python中的关键字def会告诉我们需要编写一个函数了。这就是函数定义,还肯再括号内指出函数为完成其任务所需要的信息。
在def 函数名后面:缩进的部分构成了函数体,三个引号是文档字符串的注释描述函数的作用。
函数调用会让Python执行函数,我们只需要依次支出函数名以及括起来的必要信息。

1.向函数传递信息

我们可以修改这个简单的函数。在函数的括号内添加元素。

def great_user(username):
    """"打一个简单的招呼"""
    print("Hello "+username.title()+"!")

great_user('jack')

2.实参和形参

在这个函数中,username是形参,而jack是一个实参。实参是调用函数时传递给函数的信息。

二 传递实参

1.位置实参

调用函数时,我们调用的每一个实参都要对应到位置实参。最简单的方式就是基于实参的顺序,这就是位置实参。

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('hamster', 'harry')
a.调用函数多次

函数可以调用多次,进行多次输出

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('hamster', 'harry')
describe_pet('dog','pt')
b.位置实参的顺序很重要

注意,位置参数位置关联必须正确,不然会导致输出时的错乱

2.关键字实参

关键字实参是传递给函数的名称——值对。我们直接在实参中将名称与值关联起来。因此向函数传递实参无需考虑函数调用中的实参顺序。
对上面的例子进行重新编辑:

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(animal_type='hamster', pet_name='harry')

在调用这个这个函数时,我们准确无误地向Python指出了形参对应的实参。
注意:使用关键字实参时,务必要准确定义函数的形参名**

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(pet_name='harry')

4.等效的函数调用

对于默认值类型的定义,我们要知道的是必须给未取默认值的部分提供实参,很多种调用方式其实是等效的,例如:

# 一条名为 Willie 的小狗
describe_pet('willie')
describe_pet(pet_name='willie')

# 一只名为 Harry 的仓鼠
describe_pet('harry', 'hamster')
describe_pet(pet_name='harry', animal_type='hamster')
describe_pet(animal_type='hamster', pet_name='harry')

5.避免实参错误

当我们使用函数后,提供的实参不能多于或少于函数完成工作所需的信息时,将出现实参不匹配错误。

三 返回值

1.返回简单值

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

y = get_formatted_name('p','t')
print(y.title())

该程序将函数返回的值存储在了y里,再通过print输出出来。

2.让实参变成可选的

还是以该程序举例:

def get_formatted_name(first_name, middle_name, last_name):
    """ 返回整洁的姓名 """
    full_name = first_name + ' ' + middle_name + ' ' + last_name
    return full_name.title()

musician = get_formatted_name('john', 'lee', 'hooker')
print(musician)

此时存在一些人有中间名,自然有一些人是没有中间名的,我们需要是需要分开讨论的,即把实参变成可选的:

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('john', 'lee', 'hooker')
print(musician)

musician = get_formatted_name('john','hooker')
print(musician)

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 ={
    
    'first':first_name,'last':last_name,'age':age}
    return person
musician = build_person('jimi', 'hendrix')
print(musician)
musician = build_person('x','y','z')
print(musician)

4.结合使用函数与while循环

def get_formatted_name(first_name, last_name):
    """ 返回整洁的姓名 """
    full_name = first_name + ' ' + last_name
    return full_name.title()

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 + "!")

四 传递列表

我们发现,向函数中传递列表是很有用的,因为函数可以提高处理列表的效率。

def greet_users(names):
    """ 向列表中的每位用户都发出简单的问候 """
    for name in names:
        msg = "Hello, " + name.title() + "!"
        print(msg)

usernames = ['hannah', 'ty', 'margot']
greet_users(usernames)

1.在函数中修改列表

# 首先创建一个列表,其中包含一些要打印的设计
unprinted_designs = ['iphone case', 'robot pendant', 'dodecahedron']
completed_models = []
# 模拟打印每个设计,直到没有未打印的设计为止
# 打印每个设计后,都将其移到列表 completed_models 中
while unprinted_designs:
    current_design = unprinted_designs.pop()
# 模拟根据设计制作 3D 打印模型的过程
    print("Printing model: " + current_design)
    completed_models.append(current_design)
# 显示打印好的所有模型
print("\nThe following models have been printed:")
for completed_model in completed_models:
    print(completed_model)

比如这个程序,我们可以通过编写函数进行简化。

def print_models(unprinted_designs,completed_models):
    while unprinted_designs:
        x = unprinted_designs.pop()
        print(x+" is printed")
        completed_models.append(x)

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

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

print_models(unprinted_designs,completed_models)
show_completed_models(completed_models)

2.禁止函数修改列表

如果原列表需要不动,可以只操作函数的副本:

function_name(list_name(:))

利用切片标识法创建列表的副本,这样进行输入可以避免原列表受到影响。

五 传递任意数量的实参

有时我们预先不知道函数需要接受多少个实参,而Python允许函数从调用语句中收集任意数量的实参。

def make_pizza(*toppings):
    """ 打印顾客点的所有配料 """
    print(toppings)
    
make_pizza('pepperoni')
make_pizza('mushrooms', 'green peppers', 'extra cheese')

这里形参名*toppings中的星号让Python创建一个toppings的空元组,并将收到的所有值都封装在这个元组内。

1.结合使用位置实参与任意数量实参

如果需要函数接受不同类型的实参,必须把函数定义时需要大量实参的形参放在后面。让Python先匹配位置实参和关键字实参:

def make_pizza(size, *toppings):
    """ 概述要制作的比萨 """
    print("\nMaking a " + str(size) +
    "-inch pizza with the following toppings:")
    for topping in toppings:
        print("- " + topping)
        
make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

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

有时候,需要接受任意数量的实参,但预先不知道函数会给什么样的信息,在这种情况下啊可将函数编写成能接受任意数量的键-值对。

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)

此时**user_info的两个星号让Pythin创建一个名为user_info的字典

六 将函数存储再模块中

函数的优点之一就是可以让代码块与主程序分开。极大的简化主程序,使代码变得容易理解。此时需要用到import语句

1.导入整个模块

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

def make_pizza(size, *toppings):
    """ 概述要制作的比萨 """
    print("\nMaking a " + str(size) + "-inch pizza with the following toppings:")
    for topping in toppings:
        print("- " + topping)

首先我们编写一个这样的模块。

import pizza

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

此时代码import pizza让Python打开了pizza.py的文件,并将其中的所有函数都复制到这个程序中。指定了打开的模块后,就可以在程序中使用模块的所有函数了。

2.导入特定的函数

语法如下

from module_name import function_name

3.使用as给函数指定别名

如果要导入的函数与原有程序发生冲突,或者函数名太长,我们可以指定别名。
例如:

from pizza import make_pizza as mp
mp(16, 'pepperoni')
mp(12, 'mushrooms', 'green peppers', 'extra cheese')

此时将make_pizza函数指定为mp

4.使用as给模块指定别名

同样我们可以给模块指定别名

import pizza as p
p.make_pizza(16, 'pepperoni')
p.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

一般的语法如下:
import module_name as mn

5.导入模块中的所有函数

使用from与*可以导入模块中的所有函数

from pizza import *
make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

此时让Python把模块pizza的每个函数都复制到这个程序中。无须使用句点表示法

七 函数编写指南

  • 应给函数描述性名称,且只在其中使用小写字母与下划线,方便字节和他人看懂函数
  • 每个函数都应该有简要的注释
  • 给形参指定默认值时,等号两边不要有空格
  • 对于函数调用中的关键字实参,也应该遵守这个约定

猜你喜欢

转载自blog.csdn.net/weixin_51871724/article/details/121048283