Reducing Python's startup time
I have grown to seriously dislike &#x27;namedtuple&#x27;. It seems great, and it&#x27;s so easy to use, but there&#x27;s so few places it can be used without dragging in future backwards-compatibility baggage.<p>Let&#x27;s say you have a light-weight object, like a &quot;full name&quot; which can be represented with a &quot;forename&quot; and an &quot;surname&quot;. (Yes, there are many names which don&#x27;t fit this category. This is a toy example.) So you write:<p><pre><code>  from collections import namedtuple
  FullName = namedtuple(&quot;FullName&quot;, &quot;forename surname&quot;)
  name = FullName(&quot;Edward&quot;, &quot;Smith&quot;)
</code></pre>
So simple! So clean! No &quot;self.forename = forename&quot; or need to make your own __repr__.<p>Except you also inherit the tuple behavior, because this isn&#x27;t really light-weight object but a ... let&#x27;s call it a heavy-weight tuple.<p><pre><code>  &gt;&gt;&gt; name[0]
  &#x27;Edward&#x27;
  &gt;&gt;&gt; name[1]
  &#x27;Smith&#x27;
</code></pre>
This mean people may (okay, are likely) do things like:<p><pre><code>  forename, surname = name
</code></pre>
or even<p><pre><code>  for forename, surname in names:
    ...
</code></pre>
Even if that&#x27;s not what you want in your API. If you care about backwards compatibility, then if you replace the namedtuple with its own class then you&#x27;ll have to re-implement __getitem__, _replace, __len__, and count - methods which make no sense for a simple name class.<p>Or, if you decided to change the API, to make it be:<p><pre><code>  FullName = namedtuple(&quot;FullName&quot;, &quot;forename middlename surname suffix&quot;)
</code></pre>
then you&#x27;ll again break code which used the full indexing API that you originally implicitly promised, simply by saying this is a namedtuple.<p>&#x27;namedtuple&#x27; has one good use - migration from a tuple object to a real object while allowing backwards compatability to the tuple API.  For example, the old tuples once returned from os.stat() and time.gmtime().<p>It&#x27;s also fine if it will only be used by code where you have full control over its use and can either prevent inappropriate API use like destructuring assignment, or can update all uses if you want to change the API. For example, a light-weight object used in a test-suite or internal helper function.<p>Otherwise, don&#x27;t use it. Spend the extra few minutes so in the future you don&#x27;t have to worry about backwards compatibility issues.