экземпляр не имеет атрибута (python)

У меня есть странная проблема, которую, вероятно, легко решить.

У меня есть база данных класса с методами __init__ и executeDictMore (среди прочего).

class Database():
    def __init__(self, database, server,login, password ):
        self.database = database
        my_conv = { FIELD_TYPE.LONG: int }
        self.conn = MySQLdb.Connection(user=login, passwd=password, db=self.database, host=server, conv=my_conv)
        self.cursor = self.conn.cursor()

    def executeDictMore(self, query):
        self.cursor.execute(query)
        data = self.cursor.fetchall()
        if data == None :
            return None
        result = []
        for d in data:
            desc = self.cursor.description
            dict = {}
            for (name, value) in zip(desc, d) :
                dict[name[0]] = value
            result.append(dict)
        return result

Затем я создаю экземпляр этого класса в файле db_functions.py:

from Database import Database
db = Database()

И я вызываю метод executeDictMore из функции db_functions:

def test(id):
    query = "SELECT * FROM table WHERE table_id=%s;" %(id)
    return db.executeDictMore(query)

Теперь самое странное. Если я импортирую db_functions и вызываю db_functions.test(id) из консоли Python:

import db_functions
t = db_functions.test(12)

это работает просто отлично. Но если я сделаю то же самое из другого файла Python, я получу следующую ошибку:

AttributeError: Database instance has no attribute 'executeDictMore'

Я действительно не понимаю, что здесь происходит. Я не думаю, что мне мешает другой класс базы данных. И я добавляю папку, в которой находятся модули, в sys.path, поэтому он все равно должен вызывать правильный модуль.

Если у кого-то есть идея, это очень приветствуется.


person Johanna    schedule 13.08.2013    source источник
comment
Не могли бы вы опубликовать код из другого файла Python, чтобы мы могли увидеть, как вы используете экземпляр db? Могу ли я предположить, что вы импортируете Database.py несколько раз? В этом случае может возникнуть проблема, когда db уже определена в глобальной области видимости, что может вызвать некоторые сомнительные проблемы. (просто мозговой штурм)   -  person Torxed    schedule 13.08.2013


Ответы (4)


У вас где-то есть другой Database модуль или пакет, и вместо этого он импортируется.

Чтобы диагностировать, где живет этот другой модуль, добавьте:

import Database
print Database.__file__

перед строкой from Database import Database; он напечатает имя файла модуля. Вам придется переименовать тот или иной модуль, чтобы не конфликтовать.

person Martijn Pieters    schedule 13.08.2013

Вы могли бы хотя бы попытаться избежать SQL-инъекций. Python предоставляет такие изящные способы сделать это:

def executeDictMore(self, query, data=None):
    self.cursor.execute(query, data)

а также

def test(id):
    query = "SELECT * FROM table WHERE table_id=%s"
    return db.executeDictMore(query, id)

способы сделать это.

Извините, это скорее должен быть комментарий, но ответ позволяет лучше форматировать. Я знаю, что это не отвечает на ваш вопрос...

person glglgl    schedule 13.08.2013

Вы должны вставить (не добавлять) в свой sys.path, если вы хотите, чтобы он был первым в пути поиска:

sys.path.insert(0, '/path/to/your/Database/class')
person bitfish    schedule 13.08.2013

Я не слишком уверен, что не так, но вы можете попробовать передать объект базы данных функции в качестве аргумента, например db_functions.test(db, 12), где db является вашим классом базы данных.

person terrycain    schedule 13.08.2013
comment
Я тоже думал об этом, но вам это не нужно, потому что после импорта и создания экземпляра объект db должен быть доступен из любого модуля, импортирующего файл Database.py и получающего доступ к объекту db. - person Torxed; 13.08.2013