如何将一个 Python 函数进行模块化封装


如何将一个 Python 函数进行模块化封装

文章插图
 
使用 Python 函数来最大程度地减少重复任务编码工作量 。
-- Seth Kenlon(作者)
你是否对函数、类、方法、库和模块等花哨的编程术语感到困惑?你是否在与变量作用域斗争?无论你是自学成才的还是经过正式培训的程序员 , 代码的模块化都会令人困惑 。但是类和库鼓励模块化代码 , 因为模块化代码意味着只需构建一个多用途代码块集合 , 就可以在许多项目中使用它们来减少编码工作量 。换句话说 , 如果你按照本文对 Python 函数的研究 , 你将找到更聪明的工作方法 , 这意味着更少的工作 。
本文假定你对 Python 很熟(LCTT 译注:稍微熟悉就可以) , 并且可以编写和运行一个简单的脚本 。如果你还没有使用过 Python , 请首先阅读我的文章: Python 简介。
函数函数是迈向模块化过程中重要的一步 , 因为它们是形式化的重复方法 。如果在你的程序中 , 有一个任务需要反复执行 , 那么你可以将代码放入一个函数中 , 根据需要随时调用该函数 。这样 , 你只需编写一次代码 , 就可以随意使用它 。
以下一个简单函数的示例:
#!/usr/bin/env python3import timedef Timer(): print("Time is " + str(time.time() ))创建一个名为 mymodularity 的目录 , 并将以上函数代码保存为该目录下的 timestamp.py 。
【如何将一个 Python 函数进行模块化封装】除了这个函数 , 在 mymodularity 目录中创建一个名为 __init__.py 的文件 , 你可以在文件管理器或 bash shell 中执行此操作:
$ touch mymodularity/__init__.py现在 , 你已经创建了属于你自己的 Python 库(Python 中称为“模块”) , 名为 mymodularity 。它不是一个特别有用的模块 , 因为它所做的只是导入 time 模块并打印一个时间戳 , 但这只是一个开始 。
要使用你的函数 , 像对待任何其他 Python 模块一样对待它 。以下是一个小应用 , 它使用你的 mymodularity 软件包来测试 Python sleep() 函数的准确性 。将此文件保存为 sleeptest.py , 注意要在 mymodularity 文件夹 之外 , 因为如果你将它保存在 mymodularity 里面 , 那么它将成为你的包中的一个模块 , 你肯定不希望这样 。
#!/usr/bin/env python3import timefrom mymodularity import timestampprint("Testing Python sleep()...")# modularitytimestamp.Timer()time.sleep(3)timestamp.Timer()在这个简单的脚本中 , 你从 mymodularity 包中调用 timestamp 模块两次 。从包中导入模块时 , 通常的语法是从包中导入你所需的模块 , 然后使用 模块名称 + 一个点 + 要调用的函数名(例如 timestamp.Timer()) 。
你调用了两次 Timer() 函数 , 所以如果你的 timestamp 模块比这个简单的例子复杂些 , 那么你将节省大量重复代码 。
保存文件并运行:
$ python3 ./sleeptest.pyTesting Python sleep()...Time is 1560711266.1526039Time is 1560711269.1557732根据测试 , Python 中的 sleep 函数非常准确:在三秒钟等待之后 , 时间戳成功且正确地增加了 3 , 在微秒单位上差距很小 。
Python 库的结构看起来可能令人困惑 , 但其实它并不是什么魔法 。Python 被编程 为一个包含 Python 代码的目录 , 并附带一个 __init__.py 文件 , 那么这个目录就会被当作一个包 , 并且 Python 会首先在当前目录中查找可用模块 。这就是为什么语句 from mymodularity import timestamp 有效的原因:Python 在当前目录查找名为 mymodularity 的目录 , 然后查找 timestamp.py 文件 。
你在这个例子中所做的功能和以下这个非模块化的版本是一样的:
#!/usr/bin/env python3import timefrom mymodularity import timestampprint("Testing Python sleep()...")# no modularityprint("Time is " + str(time.time() ) )time.sleep(3)print("Time is " + str(time.time() ) )对于这样一个简单的例子 , 其实没有必要以这种方式编写测试 , 但是对于编写自己的模块来说 , 最佳实践是你的代码是通用的 , 可以将它重用于其他项目 。
通过在调用函数时传递信息 , 可以使代码更通用 。例如 , 假设你想要使用模块来测试的不是 系统 的 sleep 函数 , 而是 用户自己实现 的 sleep 函数 , 更改 timestamp 代码 , 使它接受一个名为 msg 的传入变量 , 它将是一个字符串 , 控制每次调用 timestamp 时如何显示:


推荐阅读