Форум сайта python.su
Понадобилось создать getattribute, который бы получал аттрибуты из вложенных классов типа a.b.c, почемуто в голову пришел только одно более-менее достойное решение
import pdb
def recursiveGetattr(obj, lst, default):
# pdb.set_trace()
if len(lst)==1:
return getattr(obj, lst, default)
else:
_obj = getattr(obj, lst.pop(0), default)
return recursiveGetattr(_obj, lst, default)
class E(object):
def __init__(self, **kwargs):
for key in kwargs:
self.__setattr__(key, kwargs)
def getattr(self, attr, default=''):
query = attr.split('.')
if len(query) == 1:
return getattr(self, attr, default)
else:
return recursiveGetattr(self, query, default)
e = E(b='b', c='c')
a = E(a='a', e=e)
print a.e.b
print a.getattr('e.b', '')
но в нем я вижу некоторые недочеты - если незадан default - то он задается по-умолчанию, и мы полюбому получим ‘' на выходе (когда в оригинальном методе мы получаем ошибку, конечно тут можно задать ’DoNotUse' или что нибудь в таком роде, и вызывать без этого параметра)
если убрать значение по-умолчанию - то фичу нельзя будет использовать,
если заюзать **kwargs - но тогда recursiveGetattr должен принимать еще и dictionary kwargs, что еще больше уменьшает читабельность кода.
+ неочень нравится что используется рекурсия
может кто сообразит как это можно более красиво сделать?
Офлайн
На мой взгляд ты слишком усложнил задачу:
class E(object):
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
def __getattr__ (self, attr):
obj = self
for el in attr.split('.'):
obj = getattr(obj, el)
return obj
e = E(b='b', c='c')
a = E(a='a', e=e)
print a.e.b
print getattr(a, ‘e.b’)
Офлайн
а как же дефолтные значения?
Офлайн
немного усложнилось :)
class E(object):
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
def __getattr__ (self, attr):
if attr.split('.', 1) not in self.__dict__:
raise AttributeError
obj = self
for el in attr.split('.'):
obj = getattr(obj, el)
return obj
e = E(b='b', c='c')
a = E(a='a', e=e)
print a.e.b
print getattr(a, ‘e.b’)
print getattr(a, ‘e.d’, “absent”)
print getattr(a, ‘e.d’)
Офлайн
да… это - красиво =) спасибо
Офлайн