我有两个三个文件:a.py
,b.py
,c.py
。
这三个文件位于不同的目录中(我们称之为a_dir
,b_dir
,c_dir
)。
首先,我只有两个文件a.py
和b.py
。 b.py
有这个:
from root_dir.a_dir import a
...
do something
...
然后一切正常。但是当我创建第三个文件c.py
时,我将其导入a.py
,如下所示:
from root_dir.c_dir import c
...
do something
...
我开始收到pyton无法将a
导入b.py
的错误。所以我认为它可能是循环依赖?
然后我改变了导入在a.py
中的工作原理:
def method_with_c_import(s):
from root_dir.c_dir import c
...
do something inside method
...
所以我只在我需要的方法中使用了导入(我不需要在其他任何地方导入,并且b.py
中没有使用该方法。
但它是最好的方法还是有更好的方法来解决这个问题?
请求错误跟踪(如果我在文件开头的a.py
外部方法中添加了导入,则会发生这种情况):
Traceback (most recent call last):
File "/home/oerp/openerp70/openerp/server/openerp/cli/server.py", line 97, in preload_registry
db, registry = openerp.pooler.get_db_and_pool(dbname,update_module=update_module)
File "/home/oerp/openerp70/openerp/server/openerp/pooler.py", line 33, in get_db_and_pool
registry = RegistryManager.get(db_name, force_demo, status, update_module)
File "/home/oerp/openerp70/openerp/server/openerp/modules/registry.py", line 203, in get
update_module)
File "/home/oerp/openerp70/openerp/server/openerp/modules/registry.py", line 233, in new
openerp.modules.load_modules(registry.db, force_demo, status, update_module)
File "/home/oerp/openerp70/openerp/server/openerp/modules/loading.py", line 350, in load_modules
force, status, report, loaded_modules, update_module)
File "/home/oerp/openerp70/openerp/server/openerp/modules/loading.py", line 256, in load_marked_modules
loaded, processed = load_module_graph(cr, graph, progressdict, report=report, skip_modules=loaded_modules, perform_checks=perform_checks)
File "/home/oerp/openerp70/openerp/server/openerp/modules/loading.py", line 159, in load_module_graph
load_openerp_module(package.name)
File "/home/oerp/openerp70/openerp/server/openerp/modules/module.py", line 415, in load_openerp_module
getattr(sys.modules['openerp.addons.' + module_name], info['post_load'])()
File "/home/oerp/openerp70/openerp/server/openerp/addons/web/http.py", line 628, in wsgi_postload
openerp.wsgi.register_wsgi_handler(Root())
File "/home/oerp/openerp70/openerp/server/openerp/addons/web/http.py", line 517, in __init__
self.load_addons()
File "/home/oerp/openerp70/openerp/server/openerp/addons/web/http.py", line 580, in load_addons
m = __import__('openerp.addons.' + module)
File "/home/oerp/openerp70/openerp/server/openerp/modules/module.py", line 133, in load_module
mod = imp.load_module('openerp.addons.' + module_part, f, path, descr)
File "/home/oerp/openerp70/openerp/addons/ambulance_system/__init__.py", line 24, in <module>
import report
File "/home/oerp/openerp70/openerp/addons/ambulance_system/report/__init__.py", line 15, in <module>
import marketing_clinic_report
File "/home/oerp/openerp70/openerp/addons/ambulance_system/report/marketing_clinic_report.py", line 6, in <module>
from ambulance_system.model import new_medical_card as nmc
ImportError: cannot import name new_medical_card
P.S。此错误适用于我在问题b.py
中命名的文件(当我在错误跟踪之前按照上面的说明更改a.py
时)。
更新 目录的优先级导入:
import generic #c.py directory
import model #a.py directory
import report #b.py directory
UPDATE2
根据要求举例来重现问题(new_medical_card.py
为a.py
,marketing_clinic_report.py
为b.py
,generic.py
为c.py
):< / p>
模块文件和目录结构:
ambulance_system/:
- generic/generic.py
- model/new_medical_card.py
- report/marketing_clinic_report.py
导入所有三个文件:
generic.py
:
import math
new_medical_card.py
:
from openerp.osv import osv, orm, fields
import tools
from tools.translate import _
import time
from datetime import date, datetime, timedelta
ambulance_system.model.generic import generic as grc #This one produces error
marketing_clinic_report.py
:
import time
from report import report_sxw
from ambulance_system.model import new_medical_card as nmc
根据要求 Update3 init导入:
我已经显示了主init文件(根目录中的那个 - ambulance_system,但为了清楚起见,原因也会在这里发布:
__init__.py
目录的优先级导入:
import generic #c.py directory
import model #a.py directory
import report #b.py directory
__init__.py
表示通用目录(c.py
):
import generic
对于模型目录(__init__.py
) a.py
:
import new_medical_card
import medical_card_segment_res
import medical_card
import res_partner
import model_request_access
import new_medical_card_requirement
import medical_card_rule
import hr_department_team
__init__.py
报告目录(b.py
):
import card_field_report
import medical_card_field_report
import medical_card_reject_report
import new_medical_card_reject_report
import new_medical_card_field_report
import old_diagnosis_report
import new_diagnosis_report
import old_form_ambulance_usage_report
import new_form_ambulance_usage_report
import medical_card_history
import new_medical_card_history
import new_medical_card_report
import report1
import report2
import marketing_clinic_report
import print_gsc_data
答案 0 :(得分:3)
是最好的方法还是有更好的方法来解决这个问题 问题
不,这不是最好的方法!最好的方法是:
摆脱循环依赖。
真。这只意味着您在这些模块中存在设计问题。首先不应存在循环依赖。事实上,很多编程语言都不允许它们出现。
您有多种选择:
b
导入a
和c
导入a
和b
。c
可能不是必需的,可能更好,以避免首先分割a
c
)以按依赖关系对其定义进行分组。例如,c_a
将包含c
a
的所有定义,这些定义依赖于c_b
和b
所有依赖c_a
和c_b
的定义}和import
不互相导入。如果出于某种邪恶的原因,你确实希望保持循环依赖,那么可能通过放置导致import来消除错误>结束文件而不是顶部。
然而,这并不总是可行,但如果仅在函数定义中使用模块,它应该可以工作。
同样以这种方式你放松了{{1}} s的分组,这样你就不能简单地查看模块的顶部来理解模块的依赖性......但这甚至更糟当导入在函数内部时,因为在那种情况下你还必须查看多个地方。