Python模块、类与异常处理实践

18、通过使用 from 直接加载 mymod 模块的导出项,先按名称加载,然后使用 from * 变体来获取所有内容,以交互方式测试 mymod 模块。

示例代码展示了使用 from * 的情况,如 from mymod import * 后调用 countChars("mymod.py") 。若按名称加载,可将 * 替换为具体要加载的函数名,如 from mymod import countChars ,之后就可以直接调用 countChars 函数进行测试。

19、现在,在一个名为 mymod 的 Python 模块中添加一行代码,使得只有当该模块作为脚本运行时才自动调用 test 函数。尝试从系统命令行运行你的模块;然后导入该模块并交互式地测试其函数。它在这两种模式下是否仍然有效?

为了实现只有当模块作为脚本运行时才自动调用 test 函数,可以在 mymod 模块中添加以下代码:

if __name__ == '__main__':
    test()

解释:

  • __name__ 是 Python 中的一个内置变量。当一个 Python 文件作为脚本直接运行时, __name__ 的值会被设置为 '__main__' 。当该文件作为模块被导入时, __name__ 的值会是模块的名称。
  • 因此, if __name__ == '__main__': 这个条件判断可以确保 test() 函数只在模块作为脚本运行时被调用。

测试步骤:

  1. 从系统命令行运行模块 :在命令行中输入 python mymod.py ,此时 test() 函数会被自动调用。
  2. 导入模块并交互式测试 :在 Python 解释器中输入 import mymod ,此时 test() 函数不会被自动调用。你可以手动调用 mymod.test() 来测试函数。

结论:

通过这种方式, mymod 模块在作为脚本运行和作为模块导入时都能正常工作。作为脚本运行时, test() 函数会自动调用;作为模块导入时,需要手动调用 test() 函数。

20、在递归导入的场景中,导入recur1会引发错误,但如果重启Python并交互式地导入recur2,错误不会出现。请自己测试并观察,然后分析为什么导入recur2可以,而导入recur1不行。(提示:Python在运行新模块的代码之前会将其存储在内置的sys.modules表(一个字典)中;后续的导入会首先从这个表中获取模块,无论该模块是否“完整”。)现在尝试将recur1作为脚本运行:python recur1.py。你会得到与交互式导入recur1时相同的错误吗?为什么?(提示:当模块作为程序运行时,它们不会被导入,这种情况与交互式导入recur2有相同的效果;recur2是第一个被导入的模块。)当你将recur2作为脚本运行时会发生什么?

为什么导入recur2可以,而导入recur1不行

当交互式导入 recur1 时, recur1 会执行其代码。它首先给 X 赋值,然后导入 recur2 。当 recur2 执行 from recur1 import Y 时,由于 recur1 Y 还未被赋值,所以会引发 ImportError: cannot import name Y 错误。

而当交互式导入 recur2 时, recur2 首先执行 from recur1 import X ,此时 recur1 中的 X 已经被赋值,所以可以正常导入。接着,由于Python会将模块存储在 sys.modules 表中,后续的导入会首先从这个表中获取模块,即使模块不完整。所以当执行 from recur1 import Y 时,虽然 recur1 中的 Y 还未被赋值,但由于 recur1 已经在 sys.modules 表中,不会再次完整执行 recur1 的代码,避免了无限循环,只是 Y 的值还未被设置,不过不会引发错误。


将recur1作为脚本运行

当将 recur1 作为脚本运行时,它不会被导入,而是直接执行。这就相当于交互式导入 recur2 的情况,因

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值