Python 如何创建具有动态子属性的@属性?
我有一个类,Python 如何创建具有动态子属性的@属性?,python,Python,我有一个类,关税,有数量和一些价格: 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): r
关税
,有数量和一些价格:
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
如果你能接受这个,这就是我想要的
如果需要具有属性,则需要创建一个包含这些属性(或至少伪造这些属性)的对象。查看集合。此集合的名称为tuple
:
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
您可以创建一个返回子类int
,并重写\uuuu getattr\uuuu
方法,以获取动态给定单个项目的总数:
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
class TotalProperty:
def __get__(self, obj, objtype):
class Total(int):
def __getattr__(self, item):
return getattr(obj, item + '_price') * getattr(obj, item + '_selected') * obj.quantity
return Total(sum([
obj.item_1_price * obj.item_1_selected,
obj.item_2_price * obj.item_2_selected,
obj.item_3_price * obj.item_3_selected,
]) * obj.quantity)
total = TotalProperty()
以便:
purchase = Tariff()
purchase.quantity = 2
purchase.item_1_selected = True
purchase.item_2_selected = True
print(purchase.total)
print(purchase.total.item_1)
print(purchase.total.item_2)
print(purchase.total.item_3)
将输出:
1200
500
700
0
一次写的是
total
(单数),另一次写的是totals
(复数)。这些属性应该是同一个属性,还是两个独立的属性?@Aran Fey one是总属性,one是所有小计都作为子属性的属性请注意,您可能不应该使用此数据结构。为什么不制作一个项目
一个名为tuple
(或者一个类本身)并有一个项目列表呢?@AdamSmith这是我对sqlalchemy所做的简化,所以关税对象实际上是一个sqlalchemymodel@user1518321我无法想象任何底层数据结构在哪里都是正确的模型,仅此而已。