2013-07-02 54 views
15

我有一个django模型类,保持状态为一个简单的属性。我为这个类添加了一些辅助属性来访问聚合状态 - 例如is_live如果状态是['closed', 'expired', 'deleted']等中的任何一个,则返回false习惯性蟒蛇 - 财产或方法?

由于我的模型具有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 

编辑:我来自一个.NET背景原来,这里的分裂是令人钦佩的杰夫·阿特伍德定义为

“如果有任何机会,在所有的代码可能催生一个沙漏,它肯定应该是一种方法。“

编辑2:轻微的更新的问题 - 这将是把它作为一个方法的问题,所谓的is_complete,所以有混合的属性和方法具有类似名称的 - 或者是只是混乱?

所以 - 它会是这个样子:

>>> m = MyModel() 
>>> m.is_live 
True 
>>> m.is_complete() 
False 
+0

我认为它仍然是有道理的。你可以缓存结果为'self._is_complete'还是多次计算?你可以在后台运行计算,还是计算只有在评估属性时才有效? –

+0

@JaceBrowning:我有完全一样的想法(请参阅我的回答)。我认为这是好的(如果没有,它总是可以清除)。 – Tadeck

+0

@Tadeck:不用担心。我对“django”知之甚少,不知道这个应用程序是否有意义。 –

回答

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 

只要记住它“高速缓存”结果,所以第一次执行计算,但随后使用现有的结果。

+0

Thanks @tadeck - 我认为这是一种有效的方法,但是我应该问的是,是否混合了属性和方法(使用相同的命名约定 - 请参阅问题编辑2)? –

+0

@ HugoRodger-Brown:Pep8提到方法和实例变量都是'underscore_seperate_names',所以是的,它绝对没问题。由于方法和变量都返回一个布尔值,所以'is_'就是我所期望的前缀。 – TyrantWave

+0

@TyrantWave:我普遍同意。此外,好的(或平均)IDE能够判断何时是某个属性,方法或其他属性,并正确显示它。另外,我们可以期望'check_'方法不会返回任何东西(技术上说:'None'),或者接受一个回调,然后通过结果(在基于事件的方法中)。但PEP8还指出:“_项目中的一致性更重要,一个模块或功能中的一致性是最重要的。”。所以最好有一致的图书馆,而不是遵循其他人的期望。 – Tadeck