Python 为什么覆盖函数a中的datetime.datetime会影响函数b的执行?
我目前正在写一篇关于用Python进行单元测试的补丁的文章,我不明白为什么下面的方法有效。当我在该目录中执行Python 为什么覆盖函数a中的datetime.datetime会影响函数b的执行?,python,unit-testing,scope,patch,Python,Unit Testing,Scope,Patch,我目前正在写一篇关于用Python进行单元测试的补丁的文章,我不明白为什么下面的方法有效。当我在该目录中执行pytest时,测试成功,尽管我的系统时间不是在1990年 我认为datetime.datetime=NewDate只会在test\u example.py中起作用。我想我需要更好地理解Python在哪里存储导入模块的名称/指针。有人能解释一下吗 示例.py #核心库模块 导入日期时间 def generate_filename(): 返回f“{datetime.datetime.now(
pytest
时,测试成功,尽管我的系统时间不是在1990年
我认为datetime.datetime=NewDate
只会在test\u example.py
中起作用。我想我需要更好地理解Python在哪里存储导入模块的名称/指针。有人能解释一下吗
示例.py
#核心库模块
导入日期时间
def generate_filename():
返回f“{datetime.datetime.now():%Y-%m-%d}.png”
test_example.py
#核心库模块
导入日期时间
从unittest导入模拟
#第一方模块
从模拟示例导入生成文件名
类NewDate(datetime.datetime):
@类方法
def now(cls):
返回cls(1990,4,28)
def test_generate_filename():
datetime.datetime=NewDate
断言生成_filename()=“1990-04-28.png”
在您从模拟导入的行上,示例导入生成\u文件名
,执行导入日期时间
,因此datetime.datetime
的值在导入后被覆盖datetime.datetime=NewDate
。在同一程序上对任何全局变量(包括导入)进行的所有修改都会影响程序中的任何地方,无论它们位于不同的文件中
您实际上是在两个文件上访问相同的“变量”。如果您像从datetime导入datetime那样导入它(有关这方面的更多信息,请访问@Vishal Singh)只要您修补了
datetime。datetime
模块中的测试\u生成\u文件名
有两种导入需要注意
导入a
或导入a.b
(并像a.method
或a.b.method
一样使用它)从导入b
(如果在调用test\u generate\u filename
之前导入b,则会保留未打补丁的引用,如果在该模块中使用,则会提供未打补丁的内容)datetime.datetime.now()
都会返回修补的内容,即90年代的日期
如果在
示例.py
文件中尝试从datetime import datetime导入datetime之类的,则断言将失败。这就是为什么在测试中不只是用假对象替换对象,而是使用mock.patch
或类似工具,在离开范围后立即恢复修补。