Уведомления

Группа в Telegram: @pythonsu

#1 Июль 26, 2016 13:43:34

junga_py
Зарегистрирован: 2016-03-08
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Использование shelve

Здравствуйте. Есть следующий код:

 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), то код выполняется без ошибок. Но мне нужно, чтобы сохранялись и воспроизводились объекты, поддерживающие делегирование. Это вообще осуществимо?

Офлайн

#2 Июль 26, 2016 15:12:28

Stepan_M
Зарегистрирован: 2016-07-20
Сообщения: 31
Репутация: +  1  -
Профиль   Отправить e-mail  

Использование shelve

Я, конечно, могу ошибаться.
Но что, если для начала вам исправить предпоследнюю строку:

     print(x)

Офлайн

#3 Июль 26, 2016 15:27:24

junga_py
Зарегистрирован: 2016-03-08
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Использование shelve

Там всё правильно.
db2 - это объект наподобие встроенного типа dictionary, поэтому в последнем цикле переменной x последовательно присваиваются ключи, по которым осуществляется доступ к сохраненным объектам db2, и уже эти объекты передаются функции print.

Офлайн

#4 Сен. 2, 2016 14:00:46

junga_py
Зарегистрирован: 2016-03-08
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Использование shelve

Разобрался, в чем ошибка. Бесконечный цикл возникает внутри метода

 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);         

Офлайн

#5 Сен. 2, 2016 19:56:10

4kpt_IV
Зарегистрирован: 2016-01-08
Сообщения: 999
Репутация: +  49  -
Профиль   Отправить e-mail  

Использование shelve

Вообще-то эту проблему принято решать через изменения __dict__ объекта

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version