title: How to "namespace" methods in Python class
body: <p>I want a class in Python with an interface like the following:</p>
  
  <pre><code>import myclass
  
  client = myclass.Client("user", "password")
  
  client.users.create("user1")
  client.posts.create("user1", "Hello, World!")
  </code></pre>
  
  <p>Note that instead of just <code>create_user</code> or <code>create_post</code>, I want to specify the method using two dots: <code>users.create</code> / <code>posts.create</code></p>
  
  <p>I want this particular interface to mimic an HTTP API I'm trying to work with (which has endpoints like "/api/users/create" and "/api/posts/create")</p>
  
  <p>If I define my class as follows in <code>myclass.py</code>:</p>
  
  <pre><code>class Client(object):
      def __init__(self, user, pass):
          self.user = user
          self.pass = pass
  </code></pre>
  
  <p>Then how do I create these dot-namespaced methods? My first thought is to create subclasses like so:</p>
  
  <pre><code>class Client(object):
      def __init__(self, user, pass):
          self.user = user
          self.pass = pass
          self.users = ClientUserAPI()
          self.posts = ClientPostAPI()
  
  class ClientUserAPI(object):
      def create(self):
          # Do some cURL magic
  
  class ClientPostAPI(object):
      def create(self):
          # Do some cURL magic
  </code></pre>
  
  <p>However if I do this, then I run into one of two problems (one serious, the other just philosophical / ideological)</p>
  
  <ol>
  <li>If <code>ClientUserAPI</code> extends "Client" then the <code>__init__</code> method creates an infinite loop</li>
  <li>If <code>ClientUserAPI</code> extends "object" then it won't directly have access  to the <code>self.user</code> and <code>self.pass</code> variables. This means I must create <code>__init__</code> methods on both of the helper classes which do nothing but assign <code>self.user</code> and <code>self.pass</code>. This is redundant not only in code, but also in memory</li>
  </ol>
  
  <p>Is there a better solution?</p>