[英]what's the difference between property and class method?
What's the difference between a class property and a class method ?类属性和类方法有什么区别? As I understand it, property is calculated when an object is created.
据我了解,属性是在创建对象时计算的。 And method makes calculations when I call it.
当我调用它时,方法会进行计算。
Is there any other difference than that?除此之外还有什么区别吗?
For example, I have a property
in my class Product()
:例如,我的
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
When I render some page, I pass some products.当我呈现一些页面时,我传递了一些产品。 For example:
{'products':Product.objects.filter(expiration_data < datetime.now())
例如:
{'products':Product.objects.filter(expiration_data < datetime.now())
I don't need to calculate total_ammount_in_store
every time I get an instance of Product
.我不需要每次获得
Product
实例时都计算total_ammount_in_store
。 What if I just need to calculate it when I call it in a template: {{product.total_ammount_in_store}}?如果我只需要在模板中调用它时计算它呢:{{product.total_ammount_in_store}}? Is it possible?
是否可以?
Is method also calculated when the object is created?创建对象时是否也计算方法?
The property is called each time you access product.total_ammount_in_store
, not at the time when the product is created.每次访问
product.total_ammount_in_store
时都会调用该属性,而不是在创建产品时调用。
Therefore including {{ product.total_ammount_in_store }}
in your template will do the right thing.因此,在您的模板中包含
{{ product.total_ammount_in_store }}
会做正确的事情。
By using the property decorator, you can access product.total_ammount_in_store
instead of product.total_ammount_in_store()
if it was an instance method.通过使用属性装饰器,您可以访问
product.total_ammount_in_store
而不是product.total_ammount_in_store()
如果它是一个实例方法。 In the Django template language, this difference is not so apparent, because Django will call the method automatically in the template.在 Django 模板语言中,这种区别并不那么明显,因为 Django 会自动调用模板中的方法。
Don't confuse an instance method with a class method , which is quite different.不要将实例方法与类方法混淆,这是完全不同的。 A class method belongs to your class
Product
, not an individual instance product
.类方法属于您的
Product
类,而不是单个实例product
。 You don't have access to instance variables eg self.package
when you call a class method.当您调用类方法时,您无权访问实例变量,例如
self.package
。
The @property
decorator can be used to implement a getter for your class' instance variable (in your case it would be self.total_ammount_in_store
). @property
装饰器可用于为您的类的实例变量实现一个 getter(在您的情况下它将是self.total_ammount_in_store
)。 Every time you call some_product.total_ammount_in_store
, the decorated method is executed.每次调用
some_product.total_ammount_in_store
,都会执行装饰方法。 It wouldn't make sense to execute it only when a new object is created - you want to get current amount in store, don't you?仅在创建新对象时执行它是没有意义的 - 您想在商店中获取当前数量,不是吗? More reading on
@property
is in Python documentation (it's a Python's construct, not Django's):更多关于
@property
阅读在 Python 文档中(它是 Python 的构造,而不是 Django 的):
https://docs.python.org/2/library/functions.html#property https://docs.python.org/2/library/functions.html#property
As for class methods, they are something completely different.至于类方法,它们是完全不同的东西。 As the name suggests, they're tied to classes, not instances.
顾名思义,它们绑定到类,而不是实例。 Therefore, no instance is needed to call a class method, but also you can't use any instance variables in class methods (because they are tied to a particular instance).
因此,调用类方法不需要实例,但也不能在类方法中使用任何实例变量(因为它们绑定到特定实例)。
To the Django related part of your question...对于您问题中与 Django 相关的部分...
If you include {{ some_product.total_ammount_in_store }}
in your template, then every time the page is displayed, the total amount in store is obtained from the some_product
instance.如果您在模板中包含
{{ some_product.total_ammount_in_store }}
,那么每次显示页面时,都会从some_product
实例中获取 store 中的总金额。 Which means that the decorated total_ammount_in_store
getter is called.这意味着调用了装饰的
total_ammount_in_store
getter。
If for example the total amount in store isn't changed during the product's life, you can calculate the amount in __init__
method and then only return the value.例如,如果商店的总金额在产品生命周期内没有改变,您可以在
__init__
方法中计算金额,然后只返回该值。 If the total amount can change you can do it as well but you will need to ensure that the amount is re-calculated every time it should be changed - eg by calling a method.如果总金额可以更改,您也可以这样做,但您需要确保每次更改金额时都重新计算金额 - 例如通过调用方法。 Like this:
像这样:
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
Then the getter is still called every time you call some_product.total_ammount_in_store
(eg in your Django template), but it will not calculate the amount every time - it will use the stored amount instead.然后每次您调用
some_product.total_ammount_in_store
时仍然会调用some_product.total_ammount_in_store
(例如在您的 Django 模板中),但它不会每次都计算数量 - 它会使用存储的数量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.