在实践中,是否应该使一个类的所有对象具有相同数量的属性?

时间:2014-07-04 14:56:54

标签: python class coding-style

哪种编码方式更好?

示例以下(用python编写):

class sampleClass:
   def __init__( self, filter ):   #filter is a string
      self.indexed = False #no
      filterTokens = filter.split()
      if ( filterTokens[0].isdigit ):
         self.indexed = True #yes
      else:
         return
      self.action = filterTokens[1]
      self.protocol = filterTokens[2]
      self.validity = True #valid
      if ( self.protocol == 'ip' )
         #something
      elif ( self.protocol == 'tcp' )
         #someOtherThing
      else:
         self.validity = False #Invalid

现在,如果过滤器中的第一个标记不是数字,则该类的对象将只有一个属性 - 索引

上述类可能有数百个属性。在这种情况下,这是一种更好的编码实践 -

为所有对象提供相同数量的属性。 (即定义构造函数顶部的所有属性,给它们一些默认值或另一个)

或者

另一种方式(如上例所示)

例如

filter = '10 permit ip 10.10.10.0/28 20.20.20.0/28'
obj = sampleClass(filter)

1 个答案:

答案 0 :(得分:1)

唯一真正的区别在于使用你的类的代码。似乎任何这样的代码看起来都像:

if sample_instance.indexed and sample_instance.valid: # 'valid' reads better
    protocol = sample_instance.protocol

因此,在.indexed == False的情况下,.valid.protocol是否存在或是否具有任何特定值并不重要。

如果您希望调用代码获取某个属性(即使只是None),无论如何,您都可以始终__getattr__return None实现任何非属性直接解决了。


我建议将字符串解析移出__init__;考虑使用类方法来代替。此外,您在同一方法中混合不同的逻辑位。比较:

class SampleClass(object):

    PROTOCOLS = {'ip': do_this_to_ip, 
                 'tcp': but_this_to_tcp}

    def __init__(self, indexed=False, action=None, protocol=None):
        self.indexed = indexed
        self.action = action
        self.protocol = protocol

    @property
    def valid(self):
        return self.protocol in self.PROTOCOLS 

    @classmethod
    def from_string(cls, filter_): # avoid shadowing the built-in
        filter_ = filter_.split()
        if not filter_[0].isdigit():
            return cls()
        return cls(True, filter_[1], filter_[2])

将使用如下:

>>> sample = SampleClass.from_string("10 permit ip")
>>> sample.valid
True
>>> sample.protocol
'ip'
>>> sample2 = SampleClass.from_string("foo bar")
>>> sample2.valid
False

最后,你应该考虑的一个更广泛的问题是:如果实例彼此如此不同,它们真的应该是同一个类吗?