Python Circular dependencies, unable to link varia

2019-09-14 18:47发布

问题:

I am working on a program that allows me to directly edit a word document through a tkinter application. I am trying to link the tkinter input from my gui file to my main file so that I can execute my docx functions. When I try to execute my code this way, it tells me that entry in entry.get() is not defined. When I try to import this from main, I receive a circular import error.

main.py

from docx import Document
from docx.shared import Inches
import os
os.chdir("\\Users\\insanepainz\Desktop")
doc = Document('TemplateTest.docx')
paragraphs = doc.paragraphs

def WebsiteChange():
    website = entry.get()
    print(website)
    master.quit()
    for paragraph in doc.paragraphs:
        if '^website' in paragraph.text:
            paragraph.text = gui.entry
            print(paragraph.text)
            doc.save(doc)
            pass

gui.py

import main                                                                         
from tkinter import *                                                               
master = Tk()                                                                       


#------------Web Entry Window                                                       
Label(master, text="Website Name: ").grid(row=0, sticky=W)                          

entry = Entry(master)                                                               
entry.grid(row=0, column=1)                                                         

# Connect the entry with the return button                                          
submit = Button(master, text="Submit", command=main.WebsiteChange)
submit.grid(row=1)      
# Centers the program window                                                        
master.eval('tk::PlaceWindow %s center' % master.winfo_pathname(master.winfo_id())) 

mainloop()                                                                          

I have been struggling to understand this concept for awhile. Circular errors are giving me a headache. Any help would be greatly appreciated.

回答1:

The import mechanism is designed to allow circular imports. But one must remember the following:

  1. The name of the main module created from the startup script is __main__, rather than as its filename minus .py. Any other file importing the startup script must import __main__, not import filename. (Otherwise, a second module based on the startup script will be created with its normal name.)

  2. Execution of the code in a module is paused at each import. The order of initial imports is important as the last module in the chain is the first to be run to completion. Each object within modules must be available when the reference is executed. References within function definitions are not executed during the import process.

Applying the above to your pair, I assume that gui.py is the startup script. Python will immediate create an empty module object as the value of sys.modules['__main__']. Somain.pyshould importgui.pywithimport main as gui(the name change is just for convenience). Within the function definition, you should be able to usegui.entrywithout problem since there will be no attempt to lookupgui.entryuntil the function is called. I suggest addingentry = gui.entryas the first line of the function and usingentry` in the two places needed.

The following pair of files run as desired when tem2.py is run.

# tem2.py
import tem3
a = 3
print(tem3.f())

# tem3.py
import __main__ as tem2
def f():
  return tem2.a


回答2:

Move the definition of entry into a third file and import it in both files.



回答3:

You can pass the entry to WebsiteChange:

def WebsiteChange(entry):
    website = entry.get()

submit = Button(master, text="Submit", 
    command=lambda e=entry: main.WebsiteChange(e))