为什么覆盖函数 a 中的 datetime.datetime 会影响函数 b 的执行?



我目前正在写一篇关于在Python中为单元测试打补丁的文章,我很困惑为什么以下工作。当我在该目录中执行pytest时,测试成功,尽管我的系统时间不是 1990 年。

我以为datetime.datetime = NewDate只会在test_example.py内产生影响.我想我需要更好地了解 Python 存储名称/指向导入模块的指针的位置。有人可以解释一下吗?

example.py

# Core Library modules
import datetime

def generate_filename():
return f"{datetime.datetime.now():%Y-%m-%d}.png"

test_example.py

# Core Library modules
import datetime
from unittest import mock
# First party modules
from mock_example import generate_filename

class NewDate(datetime.datetime):
@classmethod
def now(cls):
return cls(1990, 4, 28)

def test_generate_filename():
datetime.datetime = NewDate
assert generate_filename() == "1990-04-28.png"

在导入from mock_example import generate_filename的行上,执行import datetime,因此datetime.datetime的值在datetime.datetime = NewDate被覆盖,因为它是在导入后执行的。在同一程序上发生的任何全局变量(包括导入(的所有修改都会影响程序中的所有位置,无论它们位于不同的文件中。

您实际上是在访问两个文件上的相同"变量"。如果您像from datetime import datetime一样导入它,则不会发生这种情况(有关此内容的更多信息,请参阅@Vishal Singh答案(

一旦你修补了test_generate_filename里面的datetime.datetime模块,你就需要注意

2种导入
  1. import aimport a.b(并像a.methoda.b.method一样使用它(
  2. from a import b(如果在调用test_generate_filename之前导入,这将留下 b 的未修补引用,如果在该模块中使用,将为您提供未修补的内容(

在您的情况下,您像import datetime一样导入它,因此没有旧的引用,并且您已经修补了模块,因此将来在任何文件中使用datetime.datetime.now()都会返回修补的内容,即 90 年代的日期。

如果您尝试在example.py文件中导入日期时间(如from datetime import datetime(,则断言将失败。

相关内容

  • 没有找到相关文章

最新更新