Комментарии 4
Похоже на выполнение домашнего задания.
Классы задача 2: а что вернет d = DictAttr(); d['pop'] = 1; print d.pop?
Классы задача 4: зачем тут метаклассы?
можно просто
class Reg(object):
__instances = []
def __init__(self):
self.__instances.append(self)
Классы задача 2: а что вернет d = DictAttr(); d['pop'] = 1; print d.pop?
Классы задача 4: зачем тут метаклассы?
можно просто
class Reg(object):
__instances = []
def __init__(self):
self.__instances.append(self)
0
1. вернет метод, потому что унаследовано от dict. Сама затея делать так — плохая и даже на хабре было пару статей с реализацией подобного словаря. И в них тоже были грабли.
2. я изначально сделал так, но не смог сделать итератор вида:
Заметьте, не такие:
а именно указанный. Если подскажете как, буду благодарен.
2. я изначально сделал так, но не смог сделать итератор вида:
for i in Reg:
Заметьте, не такие:
for i in Reg.__iter__()
for i in Reg()
for i in Reg._instances
а именно указанный. Если подскажете как, буду благодарен.
0
И вот тут, в случае неудачи, в дело вступает грязный хак. Я так и не смог придумать, как исключить возможность рекурсии, потому что необходимо проверить наличие атрибута get_KEY, которое происходит через вызов __getattr__ объекта
А как на счет такой реализации?
class XDictAttr(dict):
"""
>>> class X(XDictAttr):
... def get_foo(self):
... return 5
... def get_bar(self):
... return 12
... def get_get_z(self):
... return 42
... def get_get_get_get_get_foo(self):
... return 4242
>>> x = X({'one': 1, 'two': 2, 'three': 3})
>>> x
X: {'one': 1, 'three': 3, 'two': 2}
>>> x['one']
1
>>> x.three
3
>>> x.bar
12
>>> x['foo']
5
>>> x.get('foo', 'missing')
5
>>> x.get('bzz', 'missing')
'missing'
>>> x.get_bar()
12
>>> x.get_foz()
Traceback (most recent call last):
...
AttributeError
>>> x.get_get_z()
42
>>> x.get('get_z')
42
>>> x.get_z
42
>>> x.get_get_get_get_get_foo()
4242
>>> x.get_get_get_get_foo
4242
>>> x.get('get_get_get_get_foo')
4242
"""
def __repr__(self):
return '%s: %s' % (self.__class__.__name__, super(XDictAttr, self).__repr__())
def _get_attr_with_prefix(self, attr):
if hasattr(self, 'get_%s' % attr):
return getattr(self, 'get_%s' % attr)()
else:
raise AttributeError
def __getattr__(self, attr):
try:
return self._get_attr_with_prefix(attr)
except AttributeError:
try:
return super(XDictAttr, self).__getitem__(attr)
except KeyError:
raise AttributeError
def __getitem__(self, key):
try:
return self._get_attr_with_prefix(key)
except AttributeError:
return super(XDictAttr, self).__getitem__(key)
def get(self, key, default=None):
try:
return self._get_attr_with_prefix(key)
except AttributeError:
return super(XDictAttr, self).get(key, default)
0
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.
Ответы на вопросы с PyObject. Часть 2