属性 和 class 方法有什么区别?

what's the difference between property and class method?

class属性和class方法有什么区别?据我了解, 属性 是在创建对象时计算的。而方法在我调用的时候进行计算

还有什么不同吗?

例如,我的 class Product() 中有一个 property:

@property
    def total_ammount_in_store(self):
        consignments = self.product.package.consignments
        total_ammount = 0
        for consignment in consignments:
            total_ammount += consignment.package_ammount

当我渲染一些页面时,我传递了一些产品。例如: {'products':Product.objects.filter(expiration_data < datetime.now())

我不需要每次获取Product的实例时都计算total_ammount_in_store。如果我在模板中调用它时只需要计算它怎么办:{{product.total_ammount_in_store}}?可能吗?

方法是否也在创建对象时计算?

每次访问 product.total_ammount_in_store 时都会调用 属性,而不是在创建产品时调用。

因此,在您的模板中包含 {{ product.total_ammount_in_store }} 是正确的做法。

通过使用 属性 装饰器,如果它是一个实例方法,您可以访问 product.total_ammount_in_store 而不是 product.total_ammount_in_store()。在Django模板语言中,这种区别不是很明显,因为Django会自动调用模板中的方法。

不要将实例方法与 class method 混淆,后者是完全不同的。 class 方法属于您的 class Product,而不是单个实例 product。您无权访问实例变量,例如self.package 当您调用 class 方法时。

@property 装饰器可用于为您的 class' 实例变量实现 getter(在您的情况下为 self.total_ammount_in_store)。每次调用some_product.total_ammount_in_store,被修饰的方法都会被执行。仅在创建新对象时才执行它是没有意义的 - 你想获得当前存储量,不是吗? 更多关于 @property 的阅读在 Python 文档中(这是 Python 的构造,而不是 Django 的):

https://docs.python.org/2/library/functions.html#property

至于class方法,则完全不同。顾名思义,它们绑定到 classes,而不是实例。因此,调用 class 方法不需要实例,而且您也不能在 class 方法中使用任何实例变量(因为它们绑定到特定实例)。

对于你问题中与 Django 相关的部分...

如果您在模板中包含{{ some_product.total_ammount_in_store }},则每次显示该页面时,都会从some_product 实例中获取商店中的总金额。这意味着装饰 total_ammount_in_store getter 被调用。

例如,如果商店中的总金额在产品生命周期内没有变化,您可以使用 __init__ 方法计算金额,然后仅 return 计算值。如果总金额可以更改,您也可以这样做,但您需要确保每次更改时都重新计算金额 - 例如通过调用一个方法。像这样:

class Product(object):
    def __init__(self):
        # ...
        # other initialization
        # ...
        self.recalculate_amount()

    def recalculate_amount(self):
        consignments = self.product.package.consignments
        self._total_amount = 0
        for consignment in consignments:
            self._total_amount += consignment.package_amount

    @property
    def total_amount(self):
        """Get the current total amount in store."""
        return self._total_amount

然后每次调用 some_product.total_ammount_in_store 时仍会调用 getter(例如在您的 Django 模板中),但它不会每次都计算金额 - 它会使用存储的金额。