You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python 2.7升级至3.6后相对导入不一致问题咨询

你的相对导入问题:差异原因与统一解决方案

嘿,我来帮你理清楚这个问题——其实你遇到的差异不是Python3相对导入语法的锅,而是你修改导入语句的时候,不小心改变了导入的类型,导致代码里的命名空间内容不一样了!

先拆解两个场景的差异

  • dev.py的修改能正常运行:
    原来的from base import *和修改后的from .base import *,本质都是把base模块里的所有公开成员(非下划线开头的名字)直接导入到dev.py的命名空间里,两者的效果完全一致,只是Python3要求同包内的相对导入必须加.,所以这个修改没问题。

  • urls.py修改后报错的原因:
    你原来的代码是from . import views——这个语句是把整个views模块对象导入到urls.py的命名空间里,所以之后你可以用views.xxx(比如views.home)来访问模块里的内容;但你改成from .views import *之后,是把views模块里的所有公开成员直接导入到urls.py的命名空间里,而没有导入views这个模块对象本身。这就导致如果你的urls.py里还有直接引用views这个模块名的代码(比如urlpatterns里的path('home', views.home)),自然就会报NameError——因为当前命名空间里根本没有views这个名字!

怎么让代码保持一致又解决问题?

有两种方案可以选,看你想统一哪种风格:

方案1:统一导入模块对象的风格

如果你想继续保留views.xxx这种调用方式(和原来的代码逻辑一致),那完全可以继续用from . import views这个写法——它是Python3完全认可的相对导入语法,根本不需要改成from .views import *。这样既符合Python3的规范,又能保持代码原来的运行逻辑,不会报错。

方案2:统一导入模块成员的风格

如果你确实想把所有导入都改成from .[module] import *的形式,那你需要把代码里所有用到views.xxx的地方,直接改成xxx(因为这些成员已经被导入到当前命名空间了)。比如原来的:

path('home/', views.home)

要改成:

path('home/', home)

额外提醒:Python3相对导入的核心逻辑

再给你补个小知识点,避免以后踩坑:

  • 所有以.开头的导入都是相对导入:.代表当前包,..代表父包,以此类推;
  • from . import module → 导入整个模块对象到当前命名空间;
  • from .module import name / from .module import * → 导入模块里的具体成员到当前命名空间,不会导入模块对象本身;
  • 你这次的问题本质是混淆了这两种导入方式的命名空间差异,和Python2→3的语法变更本身无关,只是修改时误改了导入类型。

内容的提问来源于stack exchange,提问作者ravioli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:33:24