惯用蟒蛇 - 属性还是方法?

Hug*_*own 15 python django

我有一个django模型类,它将状态维护为一个简单的属性.我已经在类中添加了几个辅助属性来访问聚合状态 - 例如,is_live如果状态是任何一个状态,则返回false ['closed', 'expired', 'deleted'].

因此,我的模型有一个is_属性集合,可以对对象的内部属性进行非常简单的查找.

我现在想要添加一个新属性is_complete- 在语义上与所有其他属性相同 - 对对象状态进行布尔检查 - 但是,此检查涉及加载依赖(一对多)子对象,检查他们的状态并根据结果报告 - 即此属性实际上执行一些(多个)数据库查询,并处理结果.

那么,模型作为属性(使用@property装饰器)仍然有效,或者我应该放弃装饰器并将其作为方法保留?

使用属性的专业是它在语义上与所有其他is_属性一致.

使用方法的专业是它向其他开发人员表明这是具有更复杂实现的东西,因此应该谨慎使用(即不在for..循环内).

from django.db import models

class MyModel(models.Model):

    state = CharField(default='new')

    @property
    def is_open(self):
        # this is a simple lookup, so makes sense as a property
        return self.state in ['new', 'open', 'sent']

    def is_complete(self):
        # this is a complex database activity, but semantically correct
        related_objects = self.do_complicated_database_lookup()
        return len(related_objects)==0
Run Code Online (Sandbox Code Playgroud)

编辑:我最初来自.NET背景,其中杰夫阿特伍德的分裂是令人钦佩的

"如果有任何机会可以产生沙漏,那肯定应该是一种方法."

编辑2:对问题的轻微更新 - 将它作为一个方法调用是否有问题is_complete,因此有混合的属性和具有相似名称的方法 - 或者只是令人困惑?

所以 - 它看起来像这样:

>>> m = MyModel()
>>> m.is_live
True
>>> m.is_complete()
False
Run Code Online (Sandbox Code Playgroud)

Tad*_*eck 9

可以这样做,特别是如果你将使用以下模式:

class SomeClass(models.Model):
    @property
    def is_complete(self):
        if not hasattr(self, '_is_complete'):
            related_objects = self.do_complicated_database_lookup()
            self._is_complete = len(related_objects) == 0
        return self._is_complete
Run Code Online (Sandbox Code Playgroud)

只记得它"缓存"结果,因此首先执行计算,但随后使用现有结果.