python - 如何创建具有动态子属性的@property?
问题描述
我有一门课,Tariff
有数量和一些价格:
class Tariff():
quantity = 0
item_1_price = 250
item_1_selected = False
item_2_price = 350
item_2_selected = False
item_3_price = 165
item_3_selected = False
@property
def total(self):
return sum([
self.item_1_price * self.item_1_selected,
self.item_2_price * self.item_2_selected,
self.item_3_price * self.item_3_selected,
]) * self.quantity
我可以这样使用它:
purchase = Tariff()
purchase.quantity = 2
purchase.item_1_selected = True
purchase.item_2_selected = True
print(purchase.total)
> 1200
我想要一个可以告诉我单个项目总数的函数。例如:
print(purchase.totals.item_1)
> 500
解决这个问题的最佳方法是什么?这可能/容易吗?
解决方案
一个直接的方法是:
@property
def total(self):
return dict(
sum=sum([ self.item_1_price * self.item_1_selected,
self.item_2_price * self.item_2_selected,
self.item_3_price * self.item_3_selected,
]) * self.quantity,
item_1=item_1_price,
item_2=item_2_price,
item_3=item_3_price)
然后这将返回一个包含所有想要的信息的字典。但是,要访问 dict 中的元素,您需要使用索引语法:
print(purchase.totals['item_1'])
> 500
如果你能忍受这个,这就是我想要的。
如果您需要拥有属性,则需要创建一个包含这些属性的对象(或至少伪造它们)。看看collections.namedtuple
这个:
Totals = collections.namedtuple('total',
['item_1', 'item_2', 'item_3', 'sum'])
return Totals(sum=sum([ self.item_1_price * self.item_1_selected,
self.item_2_price * self.item_2_selected,
self.item_3_price * self.item_3_selected,
]) * self.quantity,
item_1=item_1_price,
item_2=item_2_price,
item_3=item_3_price)
然后你可以使用:
print(purchase.totals.item_1)
> 500