属性 和 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 模板中),但它不会每次都计算金额 - 它会使用存储的金额。
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 模板中),但它不会每次都计算金额 - 它会使用存储的金额。