Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preferring dictionaries over objects in Python

Are there benefits to using dictionaries instead of objects in Python (or vice versa) when all you're doing is describing something's properties?

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 why I would use an object rather than a dict.

For a mock example, one module creates Widgets and contains a method such as this:

def create(self, propertyA, propertyB=55, propertyC="default", 
           propertyD=None, propertyE=None, propertyF=None, propertyG=None,
           propertyH=None, propertyI=None):

That method would be called by creating a dictionary and passing it in much like this:

widget_client = WidgetClient()
widget = {
    "propertyA": "my_widget",
    "propertyB": 10,
    ...
}
widget_client.create(**widget)

When I see this, I see that every single one of those properties is what describes a 'Widget' and want to do the following:

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)

And then update the create() method to look something like this:

def create(self, widget):

Which ends up being called like this:

widget_client = WidgetClient()
widget = Widget(propertyA="my_widget")
widget.propertyB = 10
...
widget_client.create(widget)

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?

Dictionary Benefits:

  1. Faster and/or more memory efficient

Dictionary Drawbacks:

  1. Inability to catch some errors with static code checkers
  2. A full list of all widget properties may never appear or be known

Objects Benefits:

  1. Knowing exactly what a 'Widget' is comprised of
  2. Potentially catch errors with static code checkers (although the use of ** magic prevents some of that)

Object Drawbacks:

  1. Slower and/or less memory efficient

This seems like a silly question, but why do something with objects that can be done with dictionaries?

like image 304
Brian Lamar Avatar asked Aug 22 '26 15:08

Brian Lamar


2 Answers

No, there are no benefits to using dictionaries instead of objects - data in an object ARE normally stored in a dictionary.

There might be benefits to using objects instead of dictionaries. See: http://docs.python.org/reference/datamodel.html#slots

like image 170
rczajka Avatar answered Aug 24 '26 04:08

rczajka


Using any built-in data type always gives you the advantage of some functionality, plus its behavior is well known to other programmers. A dictionary gives you a fist-full of built in methods, and nobody has to wonder if it's iterable.

That is just one advantage. Not that I am saying you should always use dictionaries over declaring your own objects. (and of course your new object can inherit dictionary-like behaviors) But you shouldn't necessarily always opt for an creating a new object when a simpler storage mechanism may do. Using comprehension as the guide, it would depend on whether Widget had any special behaviors or attributes.

like image 22
zenWeasel Avatar answered Aug 24 '26 06:08

zenWeasel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!