在Python中的不同文件中调用变量并处理循环导入

时间:2016-06-24 16:07:36

标签: python

我目前正在使用Python构建docx / pdf转换器,并决定将文件拆分为2个文档:

main.py - 控制程序的流程;

convert_to_text.py - 包含将pdf / docx文件转换为txt的函数。

目前,我难以在两个文件中传递全局变量cv,并导入convert_to_text.py中的所有函数以在main.py中使用。这是我得到的错误:

C:\Python27\python.exe D:/cv-parser/main.py
Traceback (most recent call last):
  File "D:/cv-parser/main.py", line 1, in <module>
    from convert_to_text import *
  File "D:\cv-parser\convert_to_text.py", line 1, in <module>
    from main import cv
  File "D:\cv-parser\main.py", line 5, in <module>
    document_to_text("resources\CV.pdf")
NameError: name 'document_to_text' is not defined

Process finished with exit code 1

我该如何解决?

到目前为止,这是我的代码:

convert_to_text.py

from main import cv
import docx
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfpage import PDFPage
from cStringIO import StringIO


def document_to_text(filename):
    if filename[-5:] == ".docx":
        doc = docx.Document(filename)
        full_text = []
        for para in doc.paragraphs:
            full_text.append(para.text)
        global cv
        cv = '\n'.join(full_text)
        return cv
    elif filename[-4:] == ".pdf":
        return pdf_to_txt(filename)


def pdf_to_txt(file_path):
    rsrcmgr = PDFResourceManager()
    retstr = StringIO()
    codec = 'utf-8'
    laparams = LAParams()
    device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
    fp = file(file_path, 'rb')
    interpreter = PDFPageInterpreter(rsrcmgr, device)
    password = ""
    maxpages = 0
    caching = True
    pagenos = set()
    for page in PDFPage.get_pages(fp, pagenos, maxpages=maxpages, password=password, caching=caching,
                                  check_extractable=True):
        interpreter.process_page(page)
    fp.close()
    device.close()
    str = retstr.getvalue()
    retstr.close()
    global cv
    cv = str
    return cv

main.py

from convert_to_text import *

cv = 0

document_to_text("resources\CV.pdf")
print cv

2 个答案:

答案 0 :(得分:3)

如果您main.py中唯一需要的是cv,则只需将cv传递给需要它的函数即可。由于这些功能实际上并没有使用 cv(除了设置它之外),因此没有理由这样做。

只需移除main的导入,并使用函数的返回值设置cv即可解决整个问题:

cv = document_to_text("resources\CV.pdf")

答案 1 :(得分:2)

您需要解决循环导入问题。这是您脚本的执行路径:

  1. main.py启动
  2. main.py尝试从convert_to_text模块导入所有内容,触发convert_to_text.py的评估
  3. convert_to_text.py尝试导入主模块,再次触发main.py的评估
  4. 但是此时对main.py的评估在尝试导入convert_to_text模块时停止,因此mongoexport --db yourdb --collection mycollection --limit 100000 --out data.json 尚不存在。当遇到此错误时,解释器将保释并抛出NameError异常。

    通常,您希望避免让两个脚本相互导入。这称为循环导入。有一些方法可以使循环导入工作,但它往往是一个设计不良的程序的指标。我还没有看到循环导入的例子,无法重构为更有组织的程序。

    在这种情况下,两个模块都使用变量cv。您至少有两种可能的解决方案:

    1. 修复函数调用结构以正确传递和返回参数。此代码看起来并不真正需要在两个模块中引用cv。请参阅Bryan Oakley的答案。他在我面前指出了这一点。

    2. 如果您对使用全局变量有不健康的附件,则可以重构代码以将cv移动到main和convert_to_text都可以导入的第三个模块中,从而解析循环导入。 / p>