2

I am working on an old Python codebase. I am not in contact with anyone who had worked on the codebase previously, so I do not know why the previous developers did what they did.

In the codebase, there is a "blank" class which is used in a similar way as a dictionary. Here is a simplified example.

# Defining a "blank" class
class blank:
 pass

items = blank()

# There is a function to "add" to items by using setattr

def addItem(name, item):
 setattr(items, name, item)

addItem("att1", obj1)
addItem("att2", obj2)

# Later, items is used like this
items.att1.someFunction()
items.att2.otherFunction()

What are the advantages or disadvantages, if any, of using a class in this way instead of a dictionary?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
79037662
  • 117
  • 5
  • This used to be a recommended approach, I seem to remember. An old-fashioned dataclass, if you will. – snakecharmerb Dec 16 '22 at 21:02
  • I have used something slightly similar at one point, but it was a very rare use case. This is not otherwise common in idiomatic modern python. – Mateen Ulhaq Dec 16 '22 at 21:03
  • 1
    related SO question, in which "teaching OOP & Python" seemed to be the primary motivator: https://stackoverflow.com/questions/6203995/empty-class-object-in-python – Sarah Messer Dec 16 '22 at 21:05
  • 1
    in terms of disadvantages, the interpreter will find it harder to specialize those functions, so they will be slower in python 3.11 and future versions than other classes, especially slower than classes that use slots, other disadvantages are absence of typehints and a harder testing/desbugging. – Ahmed AEK Dec 16 '22 at 21:07
  • Quora also has this question. The answers there seem to be "defining a generic superclass so you can manage the inheritance and type-checking trees" and "defining custom exception classes which inherit the other behavior of parental exceptions": https://www.quora.com/Why-would-you-want-to-have-an-empty-class-in-Python – Sarah Messer Dec 16 '22 at 21:07
  • 1
    [This](https://docs.python.org/3/tutorial/classes.html#odds-and-ends) description of what you are talking about still exists in the official tutorial. – snakecharmerb Dec 16 '22 at 21:18
  • @snakecharmerb Wow. I tried to find the author of the commit, but https://github.com/python/cpython/commit/8ec7f656134b1230ab23003a94ba3266d7064122 is as far back as I could find, and it looks copy-pasted from somewhere even earlier. – wim Dec 16 '22 at 21:35
  • @wim it's present [here](https://svn.python.org/projects/python/branches/release20-maint/Doc/tut/) so could well have been present since 1.x (I don't know whether the original csv(?) repositories are online (on sourceforge maybe?)). My recollection is that using classes like this often recommended in the early 2.x days, when Python was less concerned about being a "proper" programming language. – snakecharmerb Dec 16 '22 at 21:56
  • I likened this idiom to dataclasses in my first comment, but named tuples were the original successor pattern. – snakecharmerb Dec 16 '22 at 22:00
  • @wim it exists in [1.4](https://docs.python.org/release/1.4/tut/node64.html#SECTION001060000000000000000). – snakecharmerb Dec 16 '22 at 22:14

1 Answers1

3

It's quaint, but it works and nothing goes wrong. If I could say anything against it, it's that you may as well just use a dict directly and use getitem/setitem syntax instead of getattr/setattr. There is a slight code smell of homesick javascript developers.

The replacement in modern Python (version 3.3+) is using a types.SimpleNamespace, instance, documented under Additional Utility Classes and Functions:

SimpleNamespace may be useful as a replacement for class NS: pass.

wim
  • 338,267
  • 99
  • 616
  • 750
  • I've never seen a Java programmer write a class without members, no matter how homesick... – Robert Dec 16 '22 at 21:22
  • Java doesn't let you dynamically add attributes to an instance of a class after the class is defined, though, either. – chepner Dec 16 '22 at 21:24
  • 2
    Javascript not Java, guys :) – 79037662 Dec 16 '22 at 21:26
  • `SimpleNamespace`, though, seems more like a belated, after-the-fact attempt to provide what `argparse` defined for itself in the form of `argparse.Namespace`. – chepner Dec 16 '22 at 21:26