首页 > 解决方案 > 确认导入的 Python AttributeError / NameError

问题描述

我有两个文件,InvertedIndex.pygui.py正在处理一个倒排索引程序。这两个文件都可以正常工作,并且具有正确的导入。当我运行python InvertedIndex.py正常并将值返回到界面时,但是当我运行时python gui.py,输入我的搜索词并单击搜索我遇到了这个:

C:\Users\MTXIII\Documents\Dev\Python\Projects\InvIndex\gui\InvInd\Test>python  gui.py
Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\MTXIII\Anaconda3\lib\tkinter\__init__.py", line 1705, in __call__
    return self.func(*args)
  File "C:\Users\MTXIII\Documents\Dev\Python\Projects\InvIndex\gui\InvInd\Test\gui.py", line 17, in open
    for line in bck.index_lookup_query(Term.get()):
AttributeError: module 'InvertedIndex' has no attribute 'index_lookup_query'

此外,当我运行这些检查时,我得到NameError: name 'bck' is not definedbck是文件中给出的别名InvertedIndex.py

>>> import  gui
>>> print(bck)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'bck' is not defined
>>> print(dir(bck))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'bck' is not defined
>>> for line in bck.index_lookup_query(Term.get()):
...

我还确认 index_lookup_query 在 InvertedIndex 的命名空间内。

>>> import InvertedIndex >>> print(dir(InvertedIndex)) ['Appearance', 'Database', 'InvertedIndex', 'builtins', 'cached', 'doc', 'file', 'loader', 'name', 'package', 'spec', 'g', 'index_documents', 'index_lookup_query', 'main', 're'] >>>

我的代码如下:

gui.py

```
from tkinter import *
import InvertedIndex as bck
# from InvertedIndex import index_lookup_query

LARGE_FONT = ("Verdana", 12)
NORM_FONT = ("Verdana", 10)
SMALL_FONT = ("Verdana", 8)

def open():
    top = Toplevel()
    searching = 'Occurences of the term: ' + Term.get()
    lbl = Label(top, text=searching, width = 60, font = LARGE_FONT).pack()
    listbox = Listbox(top)
    listbox.pack()

    # for line in bck.index_lookup_query(Term.get()):
    for line in bck.index_lookup_query(Term.get()):
        listbox.insert(END, line)


#create the tkinter window.
root = Tk()
root.geometry('300x85')
# frame = Frame(root, width=100, height=15, bg='white')
# frame.pack()

# to rename the title of the root
root.title("Term Search")

#Label for entry box.
# Label(root, text = "Enter the term you would like to search for:").grid(row = 0) 


# Entry box.
Term = Entry(root, width=30)
Term.pack(side = TOP)
Term.insert(0,"Enter the term to search for:")
# Term.grid(row = 0, column = 0) 


# Search button.
search_for = "Searching for " + Term.get()
b1 = Button(root, text = "Search!", bg = 'grey', fg = "red", width = 30, command = open)
b1.pack()
# b1.grid(row = 1, column = 0) #'fg or foreground' is for coloring the contents (buttons)


mainloop()

```

倒排索引.py

```
import re
import gui as g

class Appearance:
    """
    Represents the appearance of a term in a given document, along with the
    frequency of appearances in the same one.
    """
    def __init__(self, docId, frequency):
        self.docId = docId
        self.frequency = frequency        
    def __repr__(self):
        """
        String representation of the Appearance object
        """
        return str(self.__dict__)



class Database:
    """
    In memory database representing the already indexed documents.
    """
    def __init__(self):
        self.db = dict()
    def __repr__(self):
        """
        String representation of the Database object
        """
        return str(self.__dict__)    
    def get(self, id):
        return self.db.get(id, None)    
    def add(self, document):
        """
        Adds a document to the DB.
        """
        return self.db.update({document['id']: document})
    def remove(self, document):
        """
        Removes document from DB.
        """
        return self.db.pop(document['id'], None)


class InvertedIndex:
    """
    Inverted Index class.
    """
    def __init__(self, db):
        self.index = dict()
        self.db = db
    def __repr__(self):
        """
        String representation of the Database object
        """
        return str(self.index) 

    def index_document(self, document):
        """
        Process a given document, save it to the DB and update the index.
        """

        # Remove punctuation from the text.
        clean_text = re.sub(r'[^\w\s]','', document['text'])
        terms = clean_text.split(' ')
        appearances_dict = dict()        

        # Dictionary with each term and the frequency it appears in the text.
        for term in terms:
            term_frequency = appearances_dict[term].frequency if term in appearances_dict else 0
            appearances_dict[term] = Appearance(document['id'], term_frequency + 1)

        # Update the inverted index
        update_dict = { key: [appearance]
                       if key not in self.index
                       else self.index[key] + [appearance]
                       for (key, appearance) in appearances_dict.items() }

        self.index.update(update_dict)

        # Add the document into the database
        self.db.add(document)

        return document    

    def lookup_query(self, query):
        """
        Returns the dictionary of terms with their correspondent Appearances. 
        This is a very naive search since it will just split the terms and show
        the documents where they appear.
        """
        return { term: self.index[term] for term in query.split(' ') if term in self.index }


def index_documents(index):
    document1 = {
        'id': '1',
        'text': 'It resides in a cavern on the moon.'
    }    
    document2 = {
        'id': '2',
        'text': 'The lunar brew expedition.'
    }    
    document3 = {
        'id': '3',
        'text': 'beer beer beer!'
    }  
    document4 = {
        'id': '4',
        'text': 'Space travel has changed to way we consume beer.'
    }  
    document5 = {
        'id': '5',
        'text': 'Over the moon brew.'
    }  
    document6 = {
        'id': '6',
        'text': 'Deep in the caverns of the moon, beer.'
    }  
    index.index_document(document1)
    index.index_document(document2)
    index.index_document(document3)
    index.index_document(document4)
    index.index_document(document5)
    index.index_document(document6)

def index_lookup_query(search_term):  
    db = Database()
    index = InvertedIndex(db)
    index_documents(index)
    result = index.lookup_query(search_term)
    for key, value in result.items():
        for appearance in value:
            yield '{}, {}'.format(appearance.docId, appearance.frequency)

def main():
    search_term = input('Enter term to search for: ')
    # 
    # result = index.lookup_query(search_term)


    for line in index_lookup_query(search_term):
        print(line)
    print("-----------------------------")


if __name__ == "__main__":
    main()


```

标签: python-3.xtkinterattributeerrornameerror

解决方案


你有一个循环依赖的例子。

模块1.py

import module2
module2.func()

模块2.py

import module1
def func():
    print("hello")

现在如果你跑

python module1.py

您将遇到模块 'module2' has no attribute 'func' 错误。

发生这种情况的原因是,module2.func()当您认为该行将被执行时,它并没有被执行。以下是程序的流程:

  1. import module2在第 1 行,模块 1(程序现在转到模块 2)
  2. import mudule1在第 1 行,模块 2(程序现在再次转到模块 1)
  3. import module2在第 1 行,模块 1(程序不会再次转到模块 2,因为模块 2 之前已经导入。)
  4. module2.func()在第 2 行,模块 1。(抛出一个错误,因为我们从来没有达到第 2 行模块 2 的 func 定义。所以,模块 2 还没有 func

解决此问题的最简单方法是摆脱循环导入。在您的情况下,请import gui as g从 中删除,InvertedIndex.py因为它似乎没有必要。


推荐阅读