Найти - Пользователи
Полная версия: Использование shelve
Начало » Python для новичков » Использование shelve
1
junga_py
Здравствуйте. Есть следующий код:
 import shelve
class Person:
    def __init__(self, name, job=None, pay = 0):
        self.name = name
        self.job = job
        self.pay = pay
    def __str__(self):
        return "[Person: %s, %s]" % (self.name, self.pay)
class Manager:
    def __init__(self, name, pay):
        self.person = Person(name, 'mgr', pay)           
    def __getattr__(self, attr):
        return getattr(self.person, attr);        
    def __str__(self):
        return str(self.person)        
# создание объектов
sue = Person('Sue Jackson')
michael = Person('Michael Wilson', 'dev', 19000)
john = Manager('John Smith', 50000)
# запись объектов в хранилище
db = shelve.open('persondb')
for x in (sue, michael, john):
    db[x.name] = x
db.close()
# проверка корректности записи
db2 = shelve.open('persondb')
for x in db2:
    print(db2[x])
db2.close()

При выводе информации об объекте класса Manager появляется ошибка:
Traceback (most recent call last):
File “C:\Python34\lib\shelve.py”, line 111, in __getitem__
value = self.cache
KeyError: ‘John Smith’

Если убрать из класса Manager вызовы методов getattr(self.person, attr) и str(self.person), то код выполняется без ошибок. Но мне нужно, чтобы сохранялись и воспроизводились объекты, поддерживающие делегирование. Это вообще осуществимо?
Stepan_M
Я, конечно, могу ошибаться.
Но что, если для начала вам исправить предпоследнюю строку:
     print(x)
junga_py
Там всё правильно.
db2 - это объект наподобие встроенного типа dictionary, поэтому в последнем цикле переменной x последовательно присваиваются ключи, по которым осуществляется доступ к сохраненным объектам db2, и уже эти объекты передаются функции print.
junga_py
Разобрался, в чем ошибка. Бесконечный цикл возникает внутри метода
 class Manager:
        #...
        def __getattr__(self, attr):
                return getattr(self.person, attr);  
из-за выражения self.person. В этом месте интерпретатор рекурсивно вызывает __getattr__ для аргумента ‘person’. С помощью метода базового типа __getattribute__, внутри которого исключен вызов __getattr__, удалось решить проблему:
 class Manager:
    def __getattr__(self, attr):
        return getattr(object.__getattribute__(self, 'person'), attr)   # вместо getattr(self.person, attr);         
4kpt_IV
Вообще-то эту проблему принято решать через изменения __dict__ объекта
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB