When to use a class instead of a dict
<p>User data, as follows:</p>

<pre><code>user = {"id": 1, "firstName": "Bar", "surname": "Foosson", "age": 20}
</code></pre>

<p>is sent to an application via json. </p>

<p>In many places in the code the following it done:</p>

<pre><code>user["firstName"] + " " + user["surname"]
</code></pre>

<p>which leads me to believe a function should be used:</p>

<pre><code>def name(user):
    return user["firstName"] + " " + user["surname"]
</code></pre>

<p>which in turn leads me to believe that the code should be refactored with the use of a <code>User</code> class instead, with a <code>name</code> method. Do you agree and is there any argument for not refactoring the code to use a class instead?</p>

<p>I'm sure you are hesitant to use classes because of the need to write boilerplate code.</p>

<p>But there's a nice library that may make your life easier: <a href="https://attrs.readthedocs.io/en/stable/" rel="nofollow"><code>attrs</code></a>.</p>

<p>Glyph has a post with a self-speaking title: <a href="https://glyph.twistedmatrix.com/2016/08/attrs.html" rel="nofollow">The One Python Library Everyone Needs</a>. Of course, it's an opinionated piece, but here's a quote from its <a href="https://attrs.readthedocs.io/en/stable/examples.html" rel="nofollow">Examples page</a>:</p>

<blockquote>
<pre><code>&gt;&gt;&gt; @attr.s
... class Coordinates(object):
...     x = attr.ib()
...     y = attr.ib()
</code></pre>
  
  <p>By default, all features are added, so you immediately have a fully functional data class with a nice <code>repr</code> string and comparison methods.</p>

<pre><code>&gt;&gt;&gt; c1 = Coordinates(1, 2)
&gt;&gt;&gt; c1
Coordinates(x=1, y=2)
&gt;&gt;&gt; c2 = Coordinates(x=2, y=1)
&gt;&gt;&gt; c2
Coordinates(x=2, y=1)
&gt;&gt;&gt; c1 == c2
False
</code></pre>
</blockquote>

<p>It's a quite handy library, so check it out.</p>

<p>Here's an example of your <code>User</code> class:</p>

<pre><code>import attr

@attr.s
class User(object):

    id = attr.ib()
    firstName = attr.ib()
    surname = attr.ib()
    age = attr.ib()

    @property
    def name(self):
        return '{0.firstName} {0.surname}'.format(self)

user_dict = {'id': 1, 'firstName': 'Bar', 'surname': 'Foosson', 'age': 20}
user = User(**user_dict)
assert user.name == 'Bar Foosson'
</code></pre>

python