Note that there are some explanatory texts on larger screens.

plurals
  1. POPreferring dictionaries over objects in Python
    text
    copied!<p>Are there benefits to using dictionaries instead of objects in Python (or vice versa) when all you're doing is describing something's properties?</p> <p>The project I'm working on currently has a number of places where dictionaries are used where I would have normally created objects. In my mind objects provide more structure and allow for better programmer-error checking by programs such as pylint, but it's difficult to explain <em>why</em> I would use an object rather than a dict.</p> <p>For a mock example, one module creates Widgets and contains a method such as this:</p> <pre><code>def create(self, propertyA, propertyB=55, propertyC="default", propertyD=None, propertyE=None, propertyF=None, propertyG=None, propertyH=None, propertyI=None): </code></pre> <p>That method would be called by creating a dictionary and passing it in much like this:</p> <pre><code>widget_client = WidgetClient() widget = { "propertyA": "my_widget", "propertyB": 10, ... } widget_client.create(**widget) </code></pre> <p>When I see this, I see that every single one of those properties is what describes a 'Widget' and want to do the following:</p> <pre><code>class Widget(object): """Represents a widget.""" def __init__(self, propertyA, **kwargs): """Initialize a Widget. :param propertyA: The name of the widget. :param kwargs: Additional properties may be specified (see below). :returns: None """ self.propertyA = propertyA self.propertyB = kwargs.get("propertyB", 55) self.propertyC = kwargs.get("propertyC", "default") self.propertyD = kwargs.get("propertyD", None) self.propertyE = kwargs.get("propertyE", None) self.propertyF = kwargs.get("propertyF", None) </code></pre> <p>And then update the create() method to look something like this:</p> <pre><code>def create(self, widget): </code></pre> <p>Which ends up being called like this:</p> <pre><code>widget_client = WidgetClient() widget = Widget(propertyA="my_widget") widget.propertyB = 10 ... widget_client.create(widget) </code></pre> <p>In my mind this is clearly better, but I've been wrong in the past and I can't think of how to explain myself. Of course I'm still using **kwargs which could be avoided by breaking the Widget down into smaller component/related parts and creating more objects etc etc, but I feel this is a good "first step". Does this make any sense at all?</p> <p><strong>Dictionary Benefits</strong>:</p> <ol> <li>Faster and/or more memory efficient</li> </ol> <p><strong>Dictionary Drawbacks</strong>:</p> <ol> <li>Inability to catch some errors with static code checkers</li> <li>A full list of all widget properties may never appear or be known</li> </ol> <p><strong>Objects Benefits</strong>:</p> <ol> <li>Knowing exactly what a 'Widget' is comprised of</li> <li>Potentially catch errors with static code checkers (although the use of ** magic prevents some of that)</li> </ol> <p><strong>Object Drawbacks</strong>:</p> <ol> <li>Slower and/or less memory efficient</li> </ol> <p>This seems like a silly question, but why do something with objects that can be done with dictionaries?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload