Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a class as a data container

Sometimes it makes sense to cluster related data together. I tend to do so with a dict, e.g.,

self.group = dict(a=1, b=2, c=3) print self.group['a'] 

One of my colleagues prefers to create a class

class groupClass(object):     def __init__(a, b, c):         self.a = a         self.b = b         self.c = c self.group = groupClass(1, 2, 3) print self.group.a 

Note that we are not defining any class methods.

I like to use a dict because I like to minimize the number of lines of code. My colleague thinks the code is more readable if you use a class, and it makes it easier to add methods to the class in the future.

Which do you prefer and why?

like image 763
gaefan Avatar asked Jul 28 '10 21:07

gaefan


People also ask

What is a class A container?

Jul, 2006 13. A container class is a class that is used to hold objects in memory or external storage. A container class acts as a generic holder. A container class has a predefined behavior and a well-known interface.

Is class an container Python?

Python Classes and InterfacesEvery Python class is a container of some kind, encapsulating attributes and functionality together. Python also provides built-in container types for managing data: lists, tuples, sets, and dictionaries.

What is container class what are its uses?

A container class refers to the type of container used to store or move media, for example, a box or a bin. You must create container classes if you intend to use containers. You can base your class definition on the storage capacity of the container.

What are container classes in C ++?

Containership in C++ And the class which contains the object and members of another class in this kind of relationship is called a container class. The object that is part of another object is called contained object, whereas object that contains another object as its part or attribute is called container object.


2 Answers

If you're really never defining any class methods, a dict or a namedtuple make far more sense, in my opinion. Simple+builtin is good! To each his own, though.

like image 89
Joe Kington Avatar answered Oct 06 '22 07:10

Joe Kington


Background

A summary of alternative attribute-based, data containers was presented by R. Hettinger at the SF Python's 2017 Holiday meetup. See his tweet and his slide deck. He also gave a talk at PyCon 2018 on dataclasses.

Other data container types are mentioned in this article and predominantly in Python 3 documentation (see links below).

Here is a discussion on the python-ideas mailing list on adding recordclass to the standard library.

Options

Alternatives in the Standard Library

  • collections.namedtuple: tuple with attributes (see seminal recipe)
  • typing.NamedTuple: sub-classable tuple (see this post comparing it with namedtuple)
  • types.SimpleNamespace: simple class w/optional class declaration
  • types.MappingProxy: read-only dict
  • enum.Enum: constrained collection of related constants (does behave like a class)
  • dataclasses.dataclass: mutable namedtuple with default/boilerplate-less classes

External options

  • records: mutable namedtuple (see also recordclass)
  • bunch: add attribute access to dicts (inspiration for SimpleNamedspace; see also munch (py3))
  • box: wrap dicts with dot-style lookup functionality
  • attrdict: access elements from a mapping as keys or attributes
  • fields: remove boilerplate from container classes.
  • namedlist: mutable, tuple-like containers with defaults by E. Smith
  • attrs: similar to dataclasses, packed with features (validation, converters, __slots__, etc.). See also docs on cattrs.
  • misc.: posts on making your own custom struct, object, bunch, dict proxy, etc.

Which one?

Deciding which option to use depends on the situation (see Examples below). Usually an old fashioned mutable dictionary or immutable namedtuple is good enough. Dataclasses are the newest addition (Python 3.7a) offering both mutability and optional immutability, with promise of reduced boilerplate as inspired by the attrs project.


Examples

import typing as typ import collections as ct import dataclasses as dc   # Problem: You want a simple container to hold personal data. # Solution: Try a NamedTuple. >>> class Person(typ.NamedTuple): ...     name: str ...     age: int >>> a = Person("bob", 30) >>> a Person(name='bob', age=30) 
# Problem: You need to change age each year, but namedtuples are immutable.  # Solution: Use assignable attributes of a traditional class. >>> class Person: ...     def __init__(self, name, age): ...         self.name = name ...         self.age = age >>> b = Person("bob", 30) >>> b.age = 31 >>> b <__main__.Person at 0x4e27128> 
# Problem: You lost the pretty repr and want to add comparison features. # Solution: Use included repr and eq features from the new dataclasses. >>> @dc.dataclass(eq=True) ... class Person: ...     name: str ...     age: int >>> c = Person("bob", 30) >>> c.age = 31 >>> c Person(name='bob', age=31) >>> d = Person("dan", 31) >>> c != d True 
like image 45
pylang Avatar answered Oct 06 '22 06:10

pylang