15

I would like to store a dimension namedtuple (x, y). I will only need this once in my entire program.

I could do:

Dimension = namedtuple('Dimension', ['x', 'y'])
dim = Dimension(2, 3)

but, since I'm sure this is the only Dimension I will need in the entire program, I was wondering if I could make this into one-liner that returns an object whose properties I can access like dim.x and dim.y?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Juicy
  • 11,840
  • 35
  • 123
  • 212
  • @jonrsharpe Guess this was a really dumb question then! Seems to work, thanks! – Juicy Oct 16 '14 at 13:00
  • @jonrsharpe how about posting it as an answer so the OP can accept and people can upvote? :) – Eduard Luca Oct 16 '14 at 13:03
  • There are some enum classes that let you do this... which python version are you on? two different ones are in the answer here: http://stackoverflow.com/questions/36932/how-can-i-represent-an-enum-in-python . with the standard python3+ one, it looks like this: `dimension = Enum('Dimension', (('x',2),('y', 3)))`, and with the older version (which I prefer, and have some classes based on) you do it like this: `dimension = Enum(x=2, y=3)`... – Corley Brigman Oct 16 '14 at 14:06

2 Answers2

23

There is no need for the temporary name Dimension:

dim = namedtuple('Dimension', ['x', 'y'])(2, 3)

Alternatively, you can use the three-argument form of type to create a new class and create an instance of it:

dim = type('Dimension', (object,), {'x': 2, 'y': 3})()

This object will use more memory but, unlike the namedtuple, will be mutable (this may or may not be a good thing for your use cases). It also saves an import.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
5

I've come across this issue myself a lot; what would be great is if the Python standard library had the following convenience function built in to the collections module. But in lieu of that, you can always define this yourself locally:

def make_namedtuple(class_name, **fields):
    return namedtuple(class_name, fields)(*fields.values())

With this you could instantiate a new, single-use namedtuple class for a single instance like so:

dim = make_namedtuple('Dimension', x=2, y=3)

This works for Python 3.6+[1].

[1] the **fields' order is not maintained on Python versions <3.6 (in other words, pre-PEP 468). You can still use the function, but it kind of defeats the purpose of having a class that unpacks like a tuple, imo...

CrepeGoat
  • 2,315
  • 20
  • 24