title: Would I be able to separate variables into another class but keep the usage the same?
body: <p>I'm trying to rewrite a script and I'm stuck on making it easy to use. Basically it's an assembly script (like the reverse of destruction), where you input a load of variables such as location, whether the location is absolute or relative, scale, rotation, visibility, random offset, etc, to create an animation. The first version was very non user friendly, so I'm trying to get it working nicely from the start this time.</p>
  
  <p>I've thought of how I'd like it to work, and I've managed to keep it clean, but there is a flaw. As you can see below, it'd be possible to use anything like <code>SetGroup.frame[i].save()</code>, which I don't want (and I don't want to put checks on <code>if name is None</code> throughout the class).</p>
  
  <p>Here is the code I have:</p>
  
  <pre><code>class SetGroup(object):
  
      def __init__(self, name=None, _frame_only=False):
  
          if name is None and not _frame_only:
              raise TypeError('name of group must be provided')
  
          self.selection = None
          self.origin = None
  
          self.start = None
          self.end = None
          self.offset = 0
          self.distance = None
          self.random = 0
  
          self.location = None
          self.rotation = None
          self.scale = None
          self.visibility = None
  
          if not _frame_only:
              self.frame = defaultdict(lambda: SetGroup(_frame_only=True))
  
      def save(self):
          self.load()
          #do a bit of error checking here
          self.data[self.name] = {'ObjectSelection': self.selection,
                                  'ObjectOrigin': self.origin,
                                  'FrameStart': self.start,
                                  'FrameEnd': self.end,
                                  'FrameOffset': self.offset,
                                  'FrameDistance': self.distance,
                                  'FrameRandom': self.random,
                                  'StartLocation': self.location,
                                  'StartRotation': self.rotation,
                                  'StartScale': self.scale,
                                  'StartVisibility': self.visibility,
                                  'ExtraFrames': self.frame}
          pm.fileInfo['AssemblyScript'] = StoreData().save(self.data)
  
      def load(self):
          try:
              self.data = StoreData().load(pm.fileInfo['AssemblyScript'])
          except KeyError:
              pm.fileInfo['AssemblyScript'] = StoreData().save({})
  </code></pre>
  
  <p>The way I'd like it to work is like this:</p>
  
  <pre><code>a = SetGroup('test')
  a.location = ((0, 0, 0), True)
  a.start = 0
  a.end = 10
  a.frame[5].location = ((10, 10, 10), False)
  a.frame[5].scale = ((2, 1, 1), True)
  a.save()
  </code></pre>
  
  <p>Unless anyone can think of a way which would make it more friendly to use, how would I separate <code>location</code>, <code>rotation</code>, <code>scale</code>, and <code>visibility</code> into another class and link them up again, so that they still work at the core level of the class, but also work for the frame dictionary too?</p>
  
  <p>Edit - Got it working to a basic level:</p>
  
  <pre><code>class _MovementInfo(object):
      def __init__(self, location=None, rotation=None, scale=None, visibility=None):
          self.location = location
          self.rotation = rotation
          self.scale = scale
          self.visibility = visibility
  
      def __repr__(self):
          return '_MovementInfo(location={x.location}, rotation={x.rotation}, scale={x.scale}, visibility={x.visibility}'.format(x=self)
  </code></pre>
  
  <p>Then I used this in the main class to merge the dictionaries:</p>
  
  <pre><code>self.__dict__.update({k: v for k, v in _MovementInfo().__dict__.iteritems() if '__' not in k})
  self.frame = defaultdict(_MovementInfo)
  </code></pre>