Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何创建具有动态子属性的@属性?_Python - Fatal编程技术网

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我无法想象任何底层数据结构在哪里都是正确的模型,仅此而已。