У вас есть несколько точек смущения здесь:
1) __getattribute__
перехватывает все атрибуты доступа, а это не то, что вам нужно. Вы хотите, чтобы ваш код вступал в действие только в том случае, если реального атрибута не существует, поэтому вы хотите __getattr__
.
2) Ваш __getattribute__
вызывает метод для элементов списка, но он не должен выполнять реальную работу, он должен только возвращать вызываемую вещь. Помните, что в Python x.m(a)
на самом деле два шага: сначала получите x.m
, затем вызовите эту вещь с аргументом a
. Ваша функция должна выполнять только первый шаг, а не оба.
3) Я удивлен, что все методы, которые нужно переопределить, должны быть суммированы. Неужели так много методов, которые действительно все должны быть суммированы, чтобы это стоило того?
Этот код работает, чтобы делать то, что вы хотите, но вы можете рассмотреть более явные подходы, как другие предлагают:
class Product:
def __init__(self,price,quantity):
self.price = price
self.quantity = quantity
def get_total_price(self,tax_rate):
return self.price*self.quantity*(1+tax_rate)
class Package(list):
def __init__(self,*args):
list.__init__(self,args)
def __getattr__(self,name):
if hasattr(self[0], name):
def fn(*args):
tot = 0
for product in self:
tot += getattr(product,name)(*args)
return tot
return fn
else:
raise AttributeError
Что следует отметить в этом коде: я сделал Package
не производным от Product
, потому что всю свою продуктивность он получает от делегирования элементам списка. Не используйте in dir()
, чтобы решить, имеет ли вещь атрибут, используйте hasattr
.