python学习笔记(十一)函数深入(2)
1、传递任意数量实参
有时候定义函数时,我们不知道调用语句会传入多少个实参,这时候python为我们提供了一个特殊的形参名(在形参变量名前加上一个‘*’),这使得程序在运行的时候创建了一个空元组,无论传入多少实参,都会被封装到这个元组中。看例子:
def learn_languages(*languages):
print(languages)
for language in languages:
print(language)
learn_languages('python')
learn_languages('c', 'java', 'ruby')
运行结果为:
('python',)
python
('c', 'java', 'ruby')
c
java
ruby
2、位置实参的变体
在使用位置实参传入变量的时候,也可以传入任意数量实参,但是注意,必须在定义函数时,将形参元组放在最后,至于原因相信大家也很清楚。直接来看例子:
def learn_languages(name, *languages):
print(languages)
print(name + " likes the following languages very much:")
for language in languages:
print(language)
learn_languages('Mike', 'python')
print()
learn_languages('Marry', 'c', 'java', 'ruby')
运行结果为:
('python',)
Mike likes the following languages very much:
python
('c', 'java', 'ruby')
Marry likes the following languages very much:
c
java
ruby
3、关键字实参的变体
那么相应的,函数也可以接受任意数量的关键字实参。但是用法稍微有一点不同,这一次函数希望接收到的是任意数量的键-值对。这里引入一个新概念,在函数形参的变量名前加上‘**’,这让python创建一个空字典,并将接收到的所有键-值对都封装进去。看例子:
def learn_languages(language, **learner_info):
print(language.title() + "'s learners are as followed:")
for name, age in learner_info.items():
print(name + " " + str(age) + " years old")
learn_languages(language = 'python', Mike = 18)
print()
learn_languages(language = 'java',
Mike = 20,
Marry = 18,
John = 19)
运行结果为:
Python's learners are as followed:
Mike 18 years old
Java's learners are as followed:
Mike 20 years old
Marry 18 years old
John 19 years old
实际上,我们在自定义函数的时候,可以随意混合位置实参、关键字实参和任意数量实参,关键是注意他们各自用法的特殊性即可。
4、函数与模块
这里我们回忆一下函数最主要的优点——将代码块与主程序分离,在需要的时候再利用函数名调用代码块。
这样做可以使得主程序代码更加简洁,便于理解和维护。实际上我们还可以做的更彻底一些。
这时候我们就需要了解模块这一概念。模块是扩展名为.py的文件,由此知道它实际上还是一个包含python代码的文件。但是模块的出现,使得python这一语言的功能大大增强,事实上C语言也有头文件,Java也有包。
因为模块让语言成了百家之言,比方说函数库,我们完全不需要知道其他程序员是如何实现这一功能的,但我们可以直接import模块,使用它里面封装的任何函数(只要知道用途和用法)。
下面我们根据例子做一些简单的了解:
A 导入整个模块
import module_name #导入模块
module_name.function_name() #导入之后,我们可以使用该语句调用模块内的任何函数
这里我们新建一个文件夹方便大家学习。下面所有的代码文件都会保存到该文件夹中。
先创建一个包含函数learn_languages的模块,并且保存到day_11文件夹中。
def learn_languages(name, *languages):
print("\n" + name + " is learning the followings languages:")
for language in languages:
print(language)
接下啦,我们在相同目录下(注意这一点),创建另一个文件,导入模块。
import languages
languages.learn_languages('Mike', 'python')
languages.learn_languages('Marry', 'c', 'java', 'ruby')
上面那个文件夹是import时自动生成的,这里不细讲,我们来看运行结果:
Mike is learning the followings languages:
python
Marry is learning the followings languages:
c
java
ruby
实际上,import语句让python将模块中的所有函数都复制到了第二个文件中。
B 导入特定函数
我们还可以导入模块内的特定函数,只需要提供函数名,这样程序的工作量会小很多,我们也能更方便的调用。
from module_name import function_0, function_1, function_2
function_0()
function_1()
function_2()
我们将A中第二个文件的代码改一改,其他的保持不变。
from languages import learn_languages
learn_languages('Mike', 'python')
learn_languages('Marry', 'c', 'java', 'ruby')
运行结果不变,仍为:
Mike is learning the followings languages:
python
Marry is learning the followings languages:
c
java
ruby
C 导入的同时指定别名
在导入时运用关键字as可以为模块或者函数改名(通常是为了防止与程序中已有的名称冲突,有时候也为了简化)。
import module_name as mn
from module_name import function_name as fn
以第二个文件中的代码为例
#import languages
#languages.learn_languages('Mike', 'python')
#languages.learn_languages('Marry', 'c', 'java', 'ruby')
import languages as l
l.learn_languages('Mike', 'python')
l.learn_languages('Marry', 'c', 'java', 'ruby')
或者
#from languages import learn_languages
#learn_languages('Mike', 'python')
#learn_languages('Marry', 'c', 'java', 'ruby')
from languages import learn_languages as ll
ll('Mike', 'python')
ll('Marry', 'c', 'java', 'ruby')
以上(四组)代码的运行结果都是相同的:
Mike is learning the followings languages:
python
Marry is learning the followings languages:
c
java
ruby
D 导入模块中所有函数
from module_name import *
以上代码可以导入指定模块中的所有函数,它与直接导入模块的区别就是在调用函数的时候不需要句点表示法,即直接用函数名调用即可。但我个人不建议这种用法,原因很简单——可能会重名。