isinstance() 和 type() 因导入机制不等价失败 (python/django)

3 投票
2 回答
4078 浏览
提问于 2025-04-17 11:04

在我正在做的一个Django项目中,我在视图文件里这样导入了一个表单:

#views.py
from forms import SomeForm

然后在一个测试文件里,我有:

#form_test.py
from app.forms import SomeForm    
.
.
.
self.assertTrue(isinstance(response.context['form'], SomeForm))

为什么isinstance这个函数不管用呢?

如果我查看这两个对象的类型输出,结果是这样的:

响应的上下文表单: 期望的表单:

我可以通过让views.py里的导入方式和form_test.py里的匹配来解决这个问题,但我觉得这样做不太对。

为了方便参考,文件结构如下:

  • site/
    • manage.py
    • app/
      • forms.py
      • views.py
      • tests/
        • form_test.py

2 个回答

0

一种可能的解决方法是检查类型的 __name__ 属性,不过如果你不按照正确的方法来处理,可能会遇到其他问题。

def sharetypename(obj1, obj2):
    if isinstance(obj1, type):
        c1 = obj1.__name__
    else:
        c1 = type(obj1).__name__

    if isinstance(obj2, type):
        c2 = obj2.__name__
    else:
        c2 = type(obj2).__name__

    return c1 == c2
7

isinstance 这个函数在比较的时候还会看模块的位置。比如说,response.context['form'] 这个类的模块是 forms,而 SomeForm 的模块是 app.forms。你可以通过查看 __class__.__module____module__ 来检查这一点。

为了让 isinstance 正常工作,你可以:

  • 修正 views.py 文件中的导入(推荐)
  • form_testse.py 中修改 sys.path,这样就能像 from forms import SomeForm 这样导入表单
  • 尝试使用 包内引用

撰写回答