当前位置: 首页 > 知识库问答 >
问题:

ValueError:尝试在非包中进行相对导入,以便在Flask Web App中运行独立脚本

刘高峯
2023-03-14

我有烧瓶web应用程序和它的结构如下:

/app  
    /__init__.py  
    /wsgi.py
    /app  
        /__init__.py
        /views.py  
        /models.py 
        /method.py
        /common.py
        /db_client.py
        /amqp_client.py
        /cron
            /__init.py__
            /daemon1.py
            /daemon2.py
        /static/  
            /main.css
        /templates/  
            /base.html
    /scripts  
    /nginx
    /supervisor 
    /Dockerfile 
    /docker-compose.yml

在app/app/cron中,我编写了独立的守护进程,我想在docker外部调用这些守护进程。e、 g.python daemon1。派克

从…起通用导入统计信息

从…起方法导入msapi,数据格式化程序

从…起db_客户端导入db_连接

def run_daemon():

......

......

......

如果name=="main":

run_daemon()

所以当我试图运行这个daemon1时。py its抛出值错误:尝试在非包中进行相对导入

请建议正确的导入方法以及这些守护进程的结构。

提前感谢。

共有2个答案

陈博容
2023-03-14

@Greenbergé谢谢你的解决方案,我试过了,但没有为我工作。

所以为了让事情顺利进行,我对代码做了一点修改。除了在daemon1的main中调用run_daemon()之外。py,我直接调用了函数run_daemon()。

python-m'从app.cron.daemon1导入run_daemon();run_daemon()'

因为这不是问题的确切解决方案,但事情对我有用。

贺博厚
2023-03-14

我在运行烧瓶和芹菜的应用程序中遇到了完全相同的问题。我花了太多的时间在谷歌上寻找一个简单的答案。唉,没有。

我不喜欢“python-m”语法,因为这对于在运行代码中调用函数来说并不实用。由于我的大脑看起来很小,我无法掌握其他任何答案。

因此...有错误的路和漫长的路。他们两个都(为我)工作,我相信我会受到社区的严厉批评。

走错路

您可以使用imp包直接调用模块,如下所示:

import imp
common = imp.load_source('common', os.path.dirname(os.path.abspath('__file__')) + '/common.py')
result = common.stats()  #not sure how you call stats, but you hopefully get the idea

我快速搜索了一下说这是禁忌的参考文献,但是我找不到...抱歉。

长途跋涉

此方法涉及将每个模块临时附加到路径。这对我的Docker部署非常有效,无论容器的目录结构如何,都能很好地工作。以下是步骤:

1) 必须从\uuuu init\uuuu文件中的父目录导入相关模块。这就是\uuuu init\uuuu的全部要点——允许调用其包中的模块。因此,在您的情况下,cron/\uuuuu init\uuuu应该包含:

from . import common

看起来你的目录不会比这更高,但是你也会对任何其他级别的包做同样的事情。

2)现在需要将模块的路径追加到PATH变量。你现在可以通过运行看到里面有什么:

sys。路径

正如所料,您可能不会在其中看到任何模块。这意味着,当调用common模块时,Python无法理解您想要什么。为了添加路径,您需要确定目录结构。您需要将此动态设置为更改目录的帐户。

值得注意的是,这将需要在每次模块运行时运行。我不确定您的cron模块是什么,但在我的例子中,它是芹菜。因此,只有当我启动worker和初始crontab时,它才会运行。

以下是我提出的解决方法(我相信有一种更干净的方法):

curr_path = os.getcwd()   #current path where cron is running
parrent_path = os.path.abspath(os.path.join(os.getcwd(), '..'))   #the parent directory path
parrent_dir = os.path.basename(os.path.abspath(parrent_path))   #the parent directory name
while parrent_dir <> 'project_name':    #loop until you get to the top directory - should be the project name
    parrent_path = os.path.abspath(os.path.join(par_path, '..'))  
    parrent_dir = os.path.basename(os.path.abspath(parrent_path))

在您的情况下,这可能是一个挑战,因为您有两个名为“app”的目录。您的顶级“应用程序”是我的“项目名称”。下一步,假设您已将其更改为“project_name”。

3) 现在,您可以将每个模块的路径附加到path变量:

sys。路径附加(parrent_dir'/app')

现在,如果运行sys。路径同样,您应该在那里看到/app的路径。

总而言之:确保所有\uuuuu init\uuuu都有导入,确定要导入的模块的路径,将路径附加到PATH变量。

我希望这有帮助。

 类似资料:
  • 我在configs/common中使用配置simulation.py。我知道错误了 完整错误: py:

  • 问题内容: 我的项目存在以下问题,请帮帮我!这是我的包裹的结构: 这是foo1.py的实现: 当我运行foo1时,出现错误: ValueError:尝试了相对于顶级包的相对导入 。 我可以通过以下调整来解决它: 但是我想知道是否有一种方法可以不导入sys并在其中附加父目录。 我听说,例如,如果我有.py文件’/pkg/start.py’,它调用了我的foo1模块,那么两个点就可以了。但是,有什么方

  • 为了更好地理解Python的导入系统是如何工作的,我在玩Python的导入系统时遇到了另一个问题。我有以下结构 在中有以下代码: 在中有以下内容: 但为什么?我该怎么解决呢?我正在从空闲中运行,应该被认为是一个包,因为它有文件。 第一个导入很好,但以下内容不起作用: 因为我试图从父包导入一些东西,但显然我不能,因为一些奇怪的原因。

  • 问题内容: 我知道这个问题已经被问过很多次了,但是我却无法克服这个错误。这是我的目录结构- script2.py具有: script1.py有 我也试过 这给了我:ValueError:尝试在非包中进行相对导入 任何帮助将非常感激。 问题答案: 这个答案解释了发生了什么:http://codingdict.com/questions/250 您可能正在subpackage1 /目录中运行scrip

  • 如何在Python中从低级目录导入类? 我一直在阅读如何将添加到文件夹中(或者这只是在Python2中吗?)或者如何使用,但是这些都不起作用。 通过下面的代码,我得到了:valueerror:尝试相对导入超出顶级包 文件2.py 谢谢你。

  • 我在这个导入语句中得到了“在非包中尝试相对导入”。问题在哪里? 结构:

  • 我试图遵循PEP 328,目录结构如下: 在中,我有以下导入语句 我有什么遗漏吗?

  • 问题内容: 想象一下这个目录结构: 我正在编码,我需要从中导入一些东西。我该怎么办? 我尝试过,但是得到了“未打包的相对导入尝试”。 我四处搜寻,但只发现骇客。有没有一种干净的方法? 问题答案: 每个人似乎都想告诉你应该做什么,而不仅仅是回答问题。 问题是你通过将作为参数传递给解释器而将模块作为运行。 从PEP 328: 相对导入使用模块的属性来确定该模块在包层次结构中的位置。如果模块的名称不包含