Python学习(八)函数(二)

文章目录

      • 函数
        • 3.返回值
          • 3.1 返回简单值
          • 3.2 让实参变为可选的
          • 3.3 返回字典
          • 3.4 结合使用函数和while循环
        • 4 传递列表
          • 4.1 在函数中修改列表
          • 4.2 禁止函数修改列表
        • 5 传递任意数量的实参
          • 5.1 集合使用位置实参和任意数量实参
          • 5.2 使用任意数量的关键字实参
        • 6 将函数存储在模块中
          • 6.1 导入整个模块
          • 6.2 导入特定的函数
          • 6.3 使用as给函数指定别名
          • 6.4 使用as给模块指定别名
          • 6.5 导入模块中的所有函数

函数

3.返回值

​ 函数并非总是直接显示输出,相反,它可以处理一些数据,并返回一个或者一组值。函数返回的值被称为返回值。在函数中,可使用return语句将值返回到调用函数的代码行。返回值能够将程序的大部分繁重工作移到函数中去完成,从而简化主程序。

3.1 返回简单值
def formatted_name(first_name, last_name):
    full_name = first_name + ' ' + last_name
    return full_name.title()
name = formatted_name('dana', 'hendrix')
print name

结果

Dana Hendrix

​ 该函数的通过定义形参接收名和姓,并在名和姓之间加一个空格,把组合好之后的字符串赋值给full_name变量。

​ full_name变量调用title()方法把每个单词的首字母变成大写,最后返回这个字符串。通过调用该函数返回字符串并赋值给name变量。最后打印name变量所指代的值。

​ 这样在每个需要拼接名和姓的地方。只需要调用formatted_name()函数即可。非常方便。

3.2 让实参变为可选的

​ 有时候,需要让实参变成可选的,这样使用函数就只需在必要的时候才提供额外的信息。可以使用默认值让实参变成可选的。

​ 改变一下上面的函数,添加一个中间名。

def formatted_name(first_name, middle_name, last_name):
    full_name = first_name + ' ' + middle_name + ' ' + last_name
    return full_name.title()
name = formatted_name('dana', 'lee', 'hendrix')
print name

结果

Dana Lee Hendrix

然而并非所有的人都有中间名。那应该怎么做呢。没有就不让他输入。改变一下代码。

def 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()
name = formatted_name('dana', 'hendrix' ,'lee')
name_too = formatted_name('dana', 'hendrix' )
print name
print name_too

结果

Dana Lee Hendrix
Dana Hendrix

​ 在示例中,姓名是根据三个可能提供的部分创建的。由于人都有名和姓,因此在函数定义中首先列出这两个形参。中间名是可选的,因此在函数定义中最后列出该形参,并将其默认值设置为空字符串。

Python将非空字符串解读为True。所以在判断的时候,如果输入了中间名。判断就是成立的。所以拼接出了中间名。

3.3 返回字典

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

​ 下面示例返回一个简单的字典

def build_person(first_name, last_name):
    person = {'first': first_name, 'last': last_name}
    return person
person = build_person('dana', 'hendrix')
print person

结果

{'last': 'hendrix', 'first': 'dana'}

​ 函数接收名和姓,在函数中组成一个字典并赋值给person变量。之后返回person变量所指代的数据。

​ 下面改变一下代码,让其也能存储age

def build_person(first_name, last_name, age=''):
    if age:
        person = {'first': first_name, 'last': last_name, 'age': age}
    else:
        person = {'first': first_name, 'last': last_name}
    return person
person = build_person('dana', 'hendrix',67)
print person

结果

{'age': 67, 'last': 'hendrix', 'first': 'dana'}

​ 修改后的函数在只输入名和姓的时候,会返回只有名和姓的字典,在age也输入的时候,会返回包含名和姓还有年龄的字典。

3.4 结合使用函数和while循环
def build_person(first_name, last_name, age=''):
    name = first_name + ' ' + last_name
    return name.title()


while True:
    print "\nTell me your name: "
    first_name = input("First name:")
    last_name = input("Last name:")
    name = build_person(first_name, last_name)
    print "Hello " + name

结果

Tell me your name: 
First name:"dana"
Last name:"hendrix"
Hello Dana Hendrix

这个示例没有定义结束循环的语句。所以它将一直执行下去。这里只是作为演示使用。

4 传递列表

​ 定义函数时,经常会向函数传递列表。让函数处理列表中的数据,然后返回想要的结果。

def print_user_name(names):
    for name in names:
        msg = "Hello, " + name.title() + "!"
        print msg
names = ['daba','devid']
print_user_name(names)

结果

Hello, Daba!
Hello, Devid!

​ 在示例中,向函数print_user_name()传递一个名字列表。在函数中定义了循环名字列表的代码,并打印。最后直接调用该函数。就打印出了列表中的所有名字并进行打招呼。

4.1 在函数中修改列表

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

names = ['daba','devid']
names_title = []
def update_name(names):
    while names:
        names_title.append(names.pop().title())
update_name(names)
print names_title

结果

['Devid', 'Daba']

该代码从names列表弹出名字,并转换为首字母大写,最后添加到names_title列表中。可以看到,在函数调用之前,names_title是一个空列表。但是函数调用之后,names_title列表中存在值了。说明函数对列表的数据进行了永久性的更改。

4.2 禁止函数修改列表

​ 有时候,需要禁止函数修改列表。就是要处理这个列表的一些数据,但是还希望保留原来列表中的数据。

只需要将列表的副本传递给函数,可以像下面这样做。

update_name(names[:])

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

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

5 传递任意数量的实参

​ 有时候,预先不知道函数需要接收多少个实参,好整在Python准许函数从调用语句中收集任意数量的实参。

​ 看一下下面的例子:

def print_user_name(*names):
    print names;
print_user_name("dana")
print_user_name("dava","devid")

结果

('dana',)
('dava', 'devid')

形参名*names中的*号让Python创建一个名为names的空元组,并将收到的所有值都封装到这个元组中。这个这个函数可以处理1个值,也可以处理多个值。它以类似的方式处理不同的调用,注意,Python将实参封装到一个元组中,即便函数只收到一个值也是如此。

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

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

def print_likes(name,*fruits):
    fruits_str = ""
    for fruit in fruits:
        fruits_str = fruits_str + " " + fruit
    print name.title() + " like" + fruits_str
print_likes("dana","apple","banana")
print_likes("devid","apple")

结果

Dana like apple banana
Devid like apple
5.2 使用任意数量的关键字实参

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

def build_profile(first_name, last_name, **user_info):
    profile = {'first_name': first_name, 'last_name': last_name}
    for key, value in user_info.items():
        profile[key] = value
    return profile
profile = build_profile('dana','hendrix',like_fruit = 'apple',like_ball = 'basketball')
print profile

结果

{'like_fruit': 'apple', 'first_name': 'dana', 'last_name': 'hendrix', 'like_ball': 'basketball'}

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

在编写函数时,可以以各种方式混合使用位置实参,关键字实参和任意数量的实参。知道这些实参的类型是大有裨益的。

6 将函数存储在模块中

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

​ 通过将函数存储在独立的文件中,可隐藏程序代码的细节,将重点放在高层逻辑上。这还能让你在不同的程序中重用函数。将函数存储在独立文件中后,可与其他的程序员共享这些文件而不是整个程序。知道如何导入函数还能让你使用其他程序员编写的函数库。

​ 导入模块的方法有很多种,下面对每种都作简要的介绍。

6.1 导入整个模块

​ 要让函数是可导入的,得先创建模块。模块是扩展名为.py的文件,包含要导入到程序中的代码。

function.py

def build_profile(first_name, last_name, **user_info):
    profile = {'first_name': first_name, 'last_name': last_name}
    for key, value in user_info.items():
        profile[key] = value
    return profile

test.py

import function

profile = function.build_profile('dana','hendrix',like_fruit = 'apple',like_ball = 'basketball')
print profile

运行test文件。结果如下

{'like_fruit': 'apple', 'first_name': 'dana', 'last_name': 'hendrix', 'like_ball': 'basketball'}

Python读取这个文件时,代码行import funtion让Python打开文件fuction.py,并将其中的所有函数都复制到这个程序中。你看不到复制的代码,因为这个程序运行时,Python在幕后复制这些代码。你只需知道,在test.py中,可以使用function.py中定义的所有函数。

要调用被导入的模块中的函数,可指定导入的模块名称function和函数名build_profile,并用句号分隔它们。

这就是一种导入的方法,只需要编写一条import语句并在其中指定模块名,就可以在程序中使用该模块下面的所有函数。

6.2 导入特定的函数

还可以导入模块中特定的函数,这种导入方法的语法如下

from function import function_1

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

from function import function_1,function_2,function_3

使用这种语法,调用函数时就无需使用句号。是由于在import语句中显示的导入了函数。

6.3 使用as给函数指定别名

​ 如果要导入的函数的名称可能与程序中现有的名称冲突,或者函数的名称太长,可使用简短而独一无二的别名,函数的另一个名称,类似外号。要给函数指定这种特殊外号,需要在导入时就做。

from function import build_profile as build

profile = build('dana','hendrix',like_fruit = 'apple',like_ball = 'basketball')
print profile
6.4 使用as给模块指定别名

还可以给模块指定别名。通过给模块指定简短的别名,能够更轻松的调用模块中的函数。

import function as fun

profile = fun.build_profile('dana','hendrix',like_fruit = 'apple',like_ball = 'basketball')
print profile
6.5 导入模块中的所有函数

​ 使用星号(*)运算符可让Python导入模块中的所有函数

from function import *

profile = build_profile('dana','hendrix',like_fruit = 'apple',like_ball = 'basketball')
print profile

​ import语句中的星号让Python将模块function中的每个函数都复制到这个程序文件中。由于导入了每个函数,可通过名称来调用每个函数,而无需用句号表示法。然而并非自己编写的大型模块时,最好不要采用这种导入方法,如果模块中有函数的名称与你的项目中使用的名称相同,可能导致意想不到的结果。Python可能遇到多个名称相同的函数或变量,进而覆盖函数,而不是分别导入所有函数。

​ 最佳的做法是,要么导入你需要使用的函数,要么导入整个模块并使用句号表示法。这能让代码更清晰,更容易阅读和理解。


Python学习(八)函数(二)_第1张图片

你可能感兴趣的:(点滴Python,python,后端,开发语言)