Найти - Пользователи
Полная версия: Custom __getattribute__
Начало » Python для экспертов » Custom __getattribute__
1
cybergrind
Понадобилось создать 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, что еще больше уменьшает читабельность кода.

+ неочень нравится что используется рекурсия

может кто сообразит как это можно более красиво сделать?
Viper
На мой взгляд ты слишком усложнил задачу:

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’)
cybergrind
а как же дефолтные значения?
Viper
немного усложнилось :)

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’)
cybergrind
да… это - красиво =) спасибо
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