千锋教育-做有情怀、有良心、有品质的职业教育机构

400-811-9990
手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

关注千锋学习站小程序
随时随地免费学习课程

上海
  • 北京
  • 郑州
  • 武汉
  • 成都
  • 西安
  • 沈阳
  • 广州
  • 南京
  • 深圳
  • 大连
  • 青岛
  • 杭州
  • 重庆
当前位置:重庆千锋IT培训  >  技术干货  >  使用 Python 函数进行模块化

使用 Python 函数进行模块化

来源:千锋教育
发布人:xqq
时间: 2023-11-12 07:51:09

你是否对函数、类、方法、库和模块等花哨的编程术语感到困惑?你是否在与变量作用域斗争?无论你是自学成才的还是经过正式培训的程序员,代码的模块化都会令人困惑。但是类和库鼓励模块化代码,因为模块化代码意味着只需构建一个多用途代码块集合,就可以在许多项目中使用它们来减少编码工作量。换句话说,如果你按照本文对Python函数的研究,你将找到更聪明的工作方法,这意味着更少的工作。

本文假定你对Python很熟(LCTT译注:稍微熟悉就可以),并且可以编写和运行一个简单的脚本。如果你还没有使用过Python,请首先阅读我的文章:Python简介。

函数

函数是迈向模块化过程中重要的一步,因为它们是形式化的重复方法。如果在你的程序中,有一个任务需要反复执行,那么你可以将代码放入一个函数中,根据需要随时调用该函数。这样,你只需编写一次代码,就可以随意使用它。

以下一个简单函数的示例:

#!/usr/bin/envpython3

importtime

defTimer():

print("Timeis"+str(time.time()))

创建一个名为mymodularity的目录,并将以上函数代码保存为该目录下的timestamp.py。

除了这个函数,在mymodularity目录中创建一个名为__init__.py的文件,你可以在文件管理器或bashshell中执行此操作:

$touchmymodularity/__init__.py

现在,你已经创建了属于你自己的Python库(Python中称为“模块”),名为mymodularity。它不是一个特别有用的模块,因为它所做的只是导入time模块并打印一个时间戳,但这只是一个开始。

要使用你的函数,像对待任何其他Python模块一样对待它。以下是一个小应用,它使用你的mymodularity软件包来测试Pythonsleep()函数的准确性。将此文件保存为sleeptest.py,注意要在mymodularity文件夹之外,因为如果你将它保存在mymodularity里面,那么它将成为你的包中的一个模块,你肯定不希望这样。

#!/usr/bin/envpython3

importtime

frommymodularityimporttimestamp

print("TestingPythonsleep()...")

#modularity

timestamp.Timer()

time.sleep(3)

timestamp.Timer()

在这个简单的脚本中,你从mymodularity包中调用timestamp模块两次。从包中导入模块时,通常的语法是从包中导入你所需的模块,然后使用模块名称+一个点+要调用的函数名(例如timestamp.Timer())。

你调用了两次Timer()函数,所以如果你的timestamp模块比这个简单的例子复杂些,那么你将节省大量重复代码。

保存文件并运行:

$python3./sleeptest.py

TestingPythonsleep()...

Timeis1560711266.1526039

Timeis1560711269.1557732

根据测试,Python中的sleep函数非常准确:在三秒钟等待之后,时间戳成功且正确地增加了3,在微秒单位上差距很小。

Python库的结构看起来可能令人困惑,但其实它并不是什么魔法。Python被编程为一个包含Python代码的目录,并附带一个__init__.py文件,那么这个目录就会被当作一个包,并且Python会首先在当前目录中查找可用模块。这就是为什么语句frommymodularityimporttimestamp有效的原因:Python在当前目录查找名为mymodularity的目录,然后查找timestamp.py文件。

你在这个例子中所做的功能和以下这个非模块化的版本是一样的:

#!/usr/bin/envpython3

importtime

frommymodularityimporttimestamp

print("TestingPythonsleep()...")

#nomodularity

print("Timeis"+str(time.time()))

time.sleep(3)

print("Timeis"+str(time.time()))

对于这样一个简单的例子,其实没有必要以这种方式编写测试,但是对于编写自己的模块来说,优秀的实践是你的代码是通用的,可以将它重用于其他项目。

通过在调用函数时传递信息,可以使代码更通用。例如,假设你想要使用模块来测试的不是系统的sleep函数,而是用户自己实现的sleep函数,更改timestamp代码,使它接受一个名为msg的传入变量,它将是一个字符串,控制每次调用timestamp时如何显示:

#!/usr/bin/envpython3

importtime

#更新代码

defTimer(msg):

print(str(msg)+str(time.time()))

现在函数比以前更抽象了。它仍会打印时间戳,但是它为用户打印的内容msg还是未定义的。这意味着你需要在调用函数时定义它。

Timer函数接受的msg参数是随便命名的,你可以使用参数m、message或text,或是任何对你来说有意义的名称。重要的是,当调用timestamp.Timer函数时,它接收一个文本作为其输入,将接收到的任何内容放入msg变量中,并使用该变量完成任务。

以下是一个测试测试用户正确感知时间流逝能力的新程序:

#!/usr/bin/envpython3

frommymodularityimporttimestamp

print("PresstheRETURNkey.Countto3,andpressRETURNagain.")

input()

timestamp.Timer("Startedtimerat")

print("Countto3...")

input()

timestamp.Timer("Yousleptuntil")

将你的新程序保存为response.py,运行它:

$python3./response.py

PresstheRETURNkey.Countto3,andpressRETURNagain.

Startedtimerat1560714482.3772075

Countto3...

Yousleptuntil1560714484.1628013

函数和所需参数

新版本的timestamp模块现在需要一个msg参数。这很重要,因为你的第一个应用程序将无法运行,因为它没有将字符串传递给timestamp.Timer函数:

$python3./sleeptest.py

TestingPythonsleep()...

Traceback(mostrecentcalllast):

File"./sleeptest.py",line8,in

timestamp.Timer()

TypeError:Timer()missing1requiredpositionalargument:'msg'

你能修复你的sleeptest.py应用程序,以便它能够与更新后的模块一起正确运行吗?

变量和函数

通过设计,函数限制了变量的范围。换句话说,如果在函数内创建一个变量,那么这个变量只在这个函数内起作用。如果你尝试在函数外部使用函数内部出现的变量,就会发生错误。

下面是对response.py应用程序的修改,尝试从timestamp.Timer()函数外部打印msg变量:

#!/usr/bin/envpython3

frommymodularityimporttimestamp

print("PresstheRETURNkey.Countto3,andpressRETURNagain.")

input()

timestamp.Timer("Startedtimerat")

print("Countto3...")

input()

timestamp.Timer("Yousleptfor")

print(msg)

试着运行它,查看错误:

$python3./response.py

PresstheRETURNkey.Countto3,andpressRETURNagain.

Startedtimerat1560719527.7862902

Countto3...

Yousleptfor1560719528.135406

Traceback(mostrecentcalllast):

File"./response.py",line15,in

print(msg)

NameError:name'msg'isnotdefined

应用程序返回一个NameError消息,因为没有定义msg。这看起来令人困惑,因为你编写的代码定义了msg,但你对代码的了解比Python更深入。调用函数的代码,不管函数是出现在同一个文件中,还是打包为模块,都不知道函数内部发生了什么。一个函数独立地执行它的计算,并返回你想要它返回的内容。这其中所涉及的任何变量都只是本地的:它们只存在于函数中,并且只存在于函数完成其目的所需时间内。

Return语句

如果你的应用程序需要函数中特定包含的信息,那么使用return语句让函数在运行后返回有意义的数据。

时间就是金钱,所以修改timestamp函数,以使其用于一个虚构的收费系统:

#!/usr/bin/envpython3

importtime

defTimer(msg):

print(str(msg)+str(time.time()))

charge=.02

returncharge

现在,timestamp模块每次调用都收费2美分,但最重要的是,它返回每次调用时所收取的金额。

以下一个如何使用return语句的演示:

#!/usr/bin/envpython3

frommymodularityimporttimestamp

print("PressRETURNforthetime(costs2cents).")

print("PressQRETURNtoquit.")

total=0

whileTrue:

kbd=input()

ifkbd.lower()=="q":

print("Youowe$"+str(total))

exit()

else:

charge=timestamp.Timer("Timeis")

total=total+charge

在这个示例代码中,变量charge为timestamp.Timer()函数的返回,它接收函数返回的任何内容。在本例中,函数返回一个数字,因此使用一个名为total的新变量来跟踪已经进行了多少更改。当应用程序收到要退出的信号时,它会打印总花费:

$python3./charge.py

PressRETURNforthetime(costs2cents).

PressQRETURNtoquit.

Timeis1560722430.345412

Timeis1560722430.933996

Timeis1560722434.6027434

Timeis1560722438.612629

Timeis1560722439.3649364

q

Youowe$0.1

内联函数

函数不必在单独的文件中创建。如果你只是针对一个任务编写一个简短的脚本,那么在同一个文件中编写函数可能更有意义。唯一的区别是你不必导入自己的模块,但函数的工作方式是一样的。以下是时间测试应用程序的最新迭代:

#!/usr/bin/envpython3

importtime

total=0

defTimer(msg):

print(str(msg)+str(time.time()))

charge=.02

returncharge

print("PressRETURNforthetime(costs2cents).")

print("PressQRETURNtoquit.")

whileTrue:

kbd=input()

ifkbd.lower()=="q":

print("Youowe$"+str(total))

exit()

else:

charge=Timer("Timeis")

total=total+charge

它没有外部依赖(Python发行版中包含time模块),产生与模块化版本相同的结果。它的优点是一切都位于一个文件中,缺点是你不能在其他脚本中使用Timer()函数,除非你手动复制和粘贴它。

全局变量

在函数外部创建的变量没有限制作用域,因此它被视为全局变量。

全局变量的一个例子是在charge.py中用于跟踪当前花费的total变量。total是在函数之外创建的,因此它绑定到应用程序而不是特定函数。

应用程序中的函数可以访问全局变量,但要将变量传入导入的模块,你必须像发送msg变量一样将变量传入模块。

全局变量很方便,因为它们似乎随时随地都可用,但也很难跟踪它们,很难知道哪些变量不再需要了但是仍然在系统内存中停留(尽管Python有非常好的垃圾收集机制)。

但是,全局变量很重要,因为不是所有的变量都可以是函数或类的本地变量。现在你知道了如何向函数传入变量并获得返回,事情就变得容易了。

以上内容为大家介绍了使用Python函数进行模块化,希望对大家有所帮助,如果想要了解更多Python相关知识,请关注IT培训机构:千锋教育。http://www.mobiletrain.org/

声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。

猜你喜欢LIKE

python异步中selectors的使用

2023-11-14

python交集有什么作用?

2023-11-14

pythonfloat函数怎么用

2023-11-14

最新文章NEW

pythonreversed的反向迭代

2023-11-14

python匿名函数的命名规则

2023-11-14

python使用协程的缺点

2023-11-14

相关推荐HOT

更多>>

快速通道 更多>>

最新开班信息 更多>>

网友热搜 更多>>