【问题标题】:Python/Django TypeError: relative imports require the 'package' argumentPython/Django TypeError:相对导入需要“包”参数
【发布时间】:2016-02-05 14:45:24
【问题描述】:

在使用 C 和 C++ 编写多年后,我对 python 和 django 感到有些愚蠢。我似乎无法得到一些简单的工作。我承认该错误已在许多帖子中讨论过。

我开始阅读一些 django 教程,所以我运行了“django-admin startproject mysite”,它创建了一个“mysite”文件夹。

我已经安装了 django_extensions,所以现在我正在尝试使用它的“运行脚本”。我有一个更复杂的脚本,我想稍后运行,但现在,我正在尝试调用一个简单的用户脚本,我通过这种机制在网上找到它,即

mysimplescript.py:

def run(*script_args):
print script_args

它位于'scripts'文件夹中,所以我的结构如下,外部的mysite/根目录只是我项目的一个容器:

mysite/
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        wsgi.py
    scripts
        __init__.py
        mysimplescript.py

当我按如下方式运行脚本时,我得到了相对导入错误。

python manage.py runscript .scripts.mysimplescript.py --script-args  
Testing 123

/usr/lib/python2.7/site-packages/Django-1.9.2-py2.7.egg/django/core 
/management/base.py:265:  RemovedInDjango110Warning: 
OptionParser usage for Django management commands is deprecated, use 
ArgumentParser instead

RemovedInDjango110Warning)
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/usr/lib/python2.7/site-packages/Django-1.9.2-py2.7.egg/django/core  
/management/__init__.py", line 353, in execute_from_command_line
utility.execute()
File "/usr/lib/python2.7/site-packages/Django-1.9.2-py2.7.egg/django/core 
/management/__init__.py", line 345, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/lib/python2.7/site-packages/django_extensions-1.6.1-py2.7.egg/ 
django_extensions/management/email_notifications.py", line 63, in   
run_from_argv
super(EmailNotificationCommand, self).run_from_argv(argv)
File "/usr/lib/python2.7/site-packages/Django-1.9.2-py2.7.egg/django/core 
/management/base.py", line 348, in run_from_argv
self.execute(*args, **cmd_options)
File "/usr/lib/python2.7/site-packages/django_extensions-1.6.1-py2.7.egg/ 
django_extensions/management/email_notifications.py", line 75, in execute
super(EmailNotificationCommand, self).execute(*args, **options)
File "/usr/lib/python2.7/site-packages/Django-1.9.2-py2.7.egg/django/core 
/management/base.py", line 399, in execute
output = self.handle(*args, **options)
File "/usr/lib/python2.7/site-packages/django_extensions-1.6.1-py2.7.egg/ 
django_extensions/management/utils.py", line 57, in inner
ret = func(self, *args, **kwargs)
File "/usr/lib/python2.7/site-packages/django_extensions-1.6.1-py2.7.egg/ 
django_extensions/management/commands/runscript.py", line 163, in handle
modules = find_modules_for_script(script)
File "/usr/lib/python2.7/site-packages/django_extensions-1.6.1-py2.7.egg/ 
django_extensions/management/commands/runscript.py", line 146, in  
find_modules_for_script
mod = my_import(nn)
File "/usr/lib/python2.7/site-packages/django_extensions-1.6.1-py2.7.egg/ 
django_extensions/management/commands/runscript.py", line 99, in my_import
importlib.import_module(mod)
File "/usr/lib64/python2.7/importlib/__init__.py", line 30, in import_module
raise TypeError("relative imports require the 'package' argument")
TypeError: relative imports require the 'package' argument

如果我包含调试,那么我可以看到以下@runscript.py #99: 检查 .scripts.mysimplescript.scripts.py

最初运行了一些 django 教程,设置如下:

./mysite/wsgi.py:os.environ.setdefault("DJANGO_SETTINGS_MODULE",  
"mysite.settings")
./manage.py:    os.environ.setdefault("DJANGO_SETTINGS_MODULE", 
"mysite.settings")
./mysite/settings.py:ROOT_URLCONF = 'mysite.urls'

关于该主题的一些讨论,例如[1]:python packaging for relative imports 和 [2]:How to do relative imports in Python? 建议在外部 mysite/ 目录中添加 main.py。

不过,本质上,我仍然想通过 django-extensions 调用脚本:

python manage.py runscript  <some_script>

还有一点。如果我放弃'。在文件夹之前,即

python manage.py runscript scripts.mysimplescript.py --script-args Testing 
123

然后我收到以下错误:

No (valid) module for script 'scripts.mysimplescript.py' found

仍然生成了一个“mysimplescript.pyc”。

有人可以帮帮我吗?如何让 python 识别包?提前致谢。

【问题讨论】:

  • 你试过python manage.py runscript mysimplescript吗?这似乎等同于运行 python manage.py runscript delete_all_polls 以运行 scripts/delete_all_polls.py 的示例 in the docs
  • 阿拉斯代尔,是的,我有。 python manage.py runscript mysimplescript.py --script-args Testing 123 我得到同样的错误:检查 mysimplescript.py No (valid) module for script 'mysimplescript.py' found
  • 试试mysimplescript 没有.py
  • 是的,它成功了,谢谢一百万!检查 scripts.mysimplescript ('Testing', '123')
  • 从 mysite 导入设置中签入 python >>>。也 >>> 从 mysite 导入脚本。你得到了什么?

标签: python django python-2.7 django-extensions


【解决方案1】:

例子in the docs是将脚本保存为scripts/delete_all_questions.py,然后用

python manage.py runscript delete_all_questions

在你的情况下,你的脚本是scripts/mysimplescript.py,所以你运行它

python manage.py runscript mysimplescript --script-args Testing 123

请注意,您使用模块名称mysimplescript,因此不应包含.py。 django_extensions 应用假定脚本位于 scripts 目录中,因此也不要包含它。

【讨论】:

  • Alasdair,事实证明,我之前在包含 'mysimplescript.py' 的同一个 'scripts/' 文件夹中创建了文件 'delete_all_polls.py',那么为什么我会得到 'No (有效)脚本“delete_all_polls”的模块在运行“python manage.py runscript delete_all_polls”时出现错误?有趣的是,如果你暂时去掉顶部的'from..import',模块会被识别,但'Poll'对象显然无法识别。
  • File "/usr/tester/SwFact/isg_cid-system_test_current/my_site/scripts/delete_all_polls.py",第 7 行,运行中 all_polls = Poll.objects.all() NameError: global name 'Poll ' 未定义
  • 除非你有一个应用程序Polls 和一个模型Poll,那么我预计导入会失败。文档中的示例并不理想 - 对于 Django 1.8+,如果您遵循本教程,您将拥有 from polls.models import Question。对于本教程的早期版本,应用程序将是小写的,即from polls.models import Poll。如果您不导入或定义Poll,那么NameError 也不足为奇。
  • runscript docs 中的示例现已更新,使其更符合 Django 1.8+ 的教程。
  • 谢谢,阿拉斯代尔。我发现这个 django-extensions pdf 文档似乎是最近上传的,其中包含相同的更新示例。 [2] (media.readthedocs.org/pdf/django-extensions/latest/…)
【解决方案2】:

相对导入只能从 python 包运行。您使用相对导入的目录应该: 1. 包含一个 init.py 文件 2. 可用于 PYTHONPATH(声明为路径,或具有 init.py 且在该路径上的另一个目录的子目录)

换句话说,除非你调用整个包,否则相对路径在脚本中不起作用:

$ python -m manage.py runscript mystie.scripts.mysimplescript

【讨论】:

  • 似乎 1 2 就足够了。Python 文档中的源链接将是完美的。在您的示例中,路径不是相对的(据我所知,它必须以点开头?)。但是我使用了它并投票。
【解决方案3】:

这会起作用..

python manage.py runscript mysimplescript --script-args Testing 
123

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-16
    • 2012-08-16
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-18
    • 2021-06-06
    相关资源
    最近更新 更多