HindK
HindK

Reputation: 142

In Practice, Should all the objects of a class be made to have same number of attributes?

Which is the better coding practice?

Sample the following (written in 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

Now, if the first token in filter is not a number, the object of the class will have just one attribute - indexed.

The above class could have hundreds of attributes. In such a case which is a better coding practice -

To have same number of attributes for all the objects. (i.e define all the attributes at the top of the constructor, giving them some default value or another)

Or

The other way (as in the sample above)

Eg.

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

Upvotes: 0

Views: 61

Answers (1)

jonrsharpe
jonrsharpe

Reputation: 122086

The only real difference is in the code that's using your class. It seems likely that any such code would look like:

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

so it doesn't really matter whether, in the case .indexed == False, whether or not .valid or .protocol exist or have any particular values.

If you want the calling code to get an attribute back (even if just None) whatever the case, you could always implement __getattr__ to return None for any attributes that aren't directly resolved.


I would suggest moving the string parsing out of __init__, though; consider having a class method that does that instead. Also, you are mixing different bits of logic within the same method. Compare to:

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])

Which would be used like:

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

Finally, a broader question you should consider is: if instances are going to be so different from each other, should they really be the same class?

Upvotes: 1

Related Questions