【问题标题】:Why was an old .pyc file breaking Django?为什么旧的 .pyc 文件会破坏 Django?
【发布时间】:2012-09-08 22:07:48
【问题描述】:

今天用git拉取最新的代码,出现如下错误:

ImportError at /
cannot import name Like

这可能与循环导入有关。我检查了回溯:

Traceback:
File "/Library/Python/2.7/site-packages/Django-1.4.1-py2.7.egg/django/core/handlers/base.py" in get_response
  101.                             request.path_info)
File "/Library/Python/2.7/site-packages/Django-1.4.1-py2.7.egg/django/core/urlresolvers.py" in resolve
  298.             for pattern in self.url_patterns:
File "/Library/Python/2.7/site-packages/Django-1.4.1-py2.7.egg/django/core/urlresolvers.py" in url_patterns
  328.         patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
File "/Library/Python/2.7/site-packages/Django-1.4.1-py2.7.egg/django/core/urlresolvers.py" in urlconf_module
  323.             self._urlconf_module = import_module(self.urlconf_name)
File "/Library/Python/2.7/site-packages/Django-1.4.1-py2.7.egg/django/utils/importlib.py" in import_module
  35.     __import__(name)
File "/Users/Desktop/python/mystuff/Project/Project/urls.py" in <module>
  7. admin.autodiscover()
File "/Library/Python/2.7/site-packages/Django-1.4.1-py2.7.egg/django/contrib/admin/__init__.py" in autodiscover
  29.             import_module('%s.admin' % app)
File "/Library/Python/2.7/site-packages/Django-1.4.1-py2.7.egg/django/utils/importlib.py" in import_module
  35.     __import__(name)

它看起来可能导致问题的唯一代码是urls.py。那有以下代码:

from django.contrib import admin
admin.autodiscover()

所以大约在这个时候,我注意到我们之前编写的 admin.py 文件在最近的合并中被删除了,但 admin.pyc 仍然存在。删除 .pyc 文件继续修复循环导入错误,现在一切正常。

我的问题是:这里到底发生了什么? Git 被配置为忽略所有 pyc 文件,因此在合并后 .pyc 仍然存在,即使 .py 已被删除。但是如果 .py 本身被删除,python 不应该足够聪明,不要尝试调用 .pyc 中的任何编译代码吗?

【问题讨论】:

  • 它不知道它已被删除,如果没有pypy 更旧,它实际上总是尝试使用pyc
  • 将此添加到您的 root_directory/.gitignore 文件中:*.pyc。它会告诉 git 忽略 python 字节码。让 pyc 成为 repo 的一部分并不是一个好主意,因为每个本地功能都会对其进行编辑,如果将它们推送给没有新模块的其他人,可能会导致运行时错误。

标签: python django


【解决方案1】:

不,事实上,Python 将优先使用 .pyc 文件,并且仅在以下情况下访问 .py 文件:a) 存在并且 b) 比 .pyc 文件更新。

这允许您在没有源代码的情况下以编译形式分发 Python 应用程序(尽管它不是一种代码“混淆”技术)。

【讨论】:

  • 此功能还允许 Linux 发行版将已安装软件包的 .py 文件放在一个位置,并将 .pyc 文件放在每个 Python 版本的 lib 目录中(这可能更有用应用程序)。
【解决方案2】:

不,Python(有意地,见下文)对此很愚蠢!你可以运行

find . -name '*.pyc' -delete

从您的项目目录中删除旧的.pyc 文件。

如果您使用 git,您可以set up a hook 在结帐时自动执行此操作。这是 Mercurial 的 similar solution

【讨论】:

  • 我不会称之为“愚蠢”。这是一个有意的设计决策来支持这一点,它有几个用例。这是一项功能。
  • @SvenMarnach 我认为“愚蠢”的部分是当它们坏了时它没有提供一种很好的清理方法。
【解决方案3】:

防止这种情况发生的方法是使用

启动 django
python -B manage.py runserver

或自动删除 pyc,可能使用 django-extensions 中的 clean_pyc

./manage.py clean_pyc

【讨论】:

    猜你喜欢
    • 2011-03-25
    • 2011-08-19
    • 2016-01-19
    • 1970-01-01
    • 2012-03-27
    • 2015-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多