recordclass
recordclass is a Python library that provides mutable variants of `collections.namedtuple`, supporting assignments and offering memory-saving alternatives like `dataobject` and `structclass`. These types aim for high performance and reduced memory footprint by optionally disabling cyclic garbage collection and removing instance dictionaries. Currently at version 0.24, the library is actively maintained with releases supporting the latest Python versions, including 3.14, and aims to be a fast, memory-efficient, and flexible choice for data representation.
Common errors
-
TypeError: 'X' object is not callable
cause This usually occurs when you shadow a class name with an instance of that class, then try to call the instance as if it were the class itself to create a new object. For example, `Point = recordclass(...)`, then `point = Point(...)`, and later `point = point(...)`.fixEnsure distinct variable names for classes and instances (e.g., `PointClass` and `point_instance`) or be careful about scope. A common Python convention is to capitalize class names: `Point = recordclass(...)`, then `point = Point(...)`. -
AttributeError: 'X' object has no attribute 'Y' and no __dict__ for setting new attributes
cause You are attempting to assign a new attribute (`Y`) to an instance of a `dataobject`-based class (`X`) that was not defined in the class's fields. These classes omit `__dict__` for memory efficiency, preventing dynamic attribute assignment.fixDefine all necessary attributes as fields in the `dataobject` class definition. If truly dynamic attributes are needed, `recordclass` may not be the ideal choice for that specific data structure. -
TypeError: the number of the arguments greater than the number of fields
cause This error occurs during instance creation when too many arguments (either positional or keyword) are provided compared to the fields defined in the `recordclass` or `dataobject` type. It can also happen in subclasses with custom `__init__` methods if argument handling is incorrect.fixReview the class definition and the arguments passed during instantiation. Ensure that the number and names of arguments match the defined fields, accounting for default values. If using `__init__` in a subclass, ensure it correctly calls the superclass's initializer and handles its arguments. -
Building wheel for recordclass (setup.py) ... error
cause This build error typically indicates problems compiling the C extensions of `recordclass`. Common causes include missing C build tools, incompatible Python development headers, or, historically, `recordclass` versions not yet supporting newer Python releases due to C API changes.fixEnsure you have C/C++ build tools installed (e.g., `build-essential` on Debian/Ubuntu, Xcode Command Line Tools on macOS, Visual C++ Build Tools on Windows). Upgrade `recordclass` to the latest version (0.24) as it includes fixes for newer Python versions.
Warnings
- gotcha Mutable Default Values: When defining `dataobject` classes with mutable default values (e.g., lists, dicts), the default object is shared across all instances. This is a common Python pitfall. Use `copy_default=True` or `recordclass.Factory` for independent defaults.
- breaking Attribute Deletion Not Allowed: Attempting to delete an attribute using `del instance.attribute` will raise an `AttributeError`. This was explicitly disallowed for `dataobject`-based classes in recent versions to maintain internal structure.
- gotcha No `__dict__` by Default in `dataobject`: `dataobject`-based classes do not have an instance `__dict__` or `__weakref__` by default for memory optimization. This means you cannot add new attributes to instances after creation, which can lead to `AttributeError`.
- breaking Python Version Compatibility (older versions): Older versions of `recordclass` (e.g., <0.24) had known build and runtime issues with newer Python interpreters (e.g., Python 3.9, 3.12, 3.14) due to internal C API changes. This often manifested as build errors during `pip install`.
Install
-
pip install recordclass
Imports
- recordclass
from recordclass import recordclass
- dataobject
from recordclass import dataobject
- make_dataclass
from recordclass import make_dataclass
- as_record
from recordclass import as_record
- mutabletuple
from recordclass import mutabletuple
Quickstart
from recordclass import recordclass, dataobject, make_dataclass, as_record
import os
# Using recordclass (mutable namedtuple-like)
Point = recordclass('Point', 'x y')
p = Point(1, 2)
print(f"Initial Point: {p}")
p.x = 10
print(f"Modified Point: {p}")
# Using dataobject (compact dataclass-like)
class ColorPoint(dataobject):
x: int
y: int
color: str = 'red'
cp = ColorPoint(1, 2)
print(f"ColorPoint: {cp}")
cp.color = 'blue'
print(f"Modified ColorPoint: {cp}")
# Using make_dataclass
User = make_dataclass("User", [("name", str), ("age", int)])
u = User("Alice", 30)
print(f"User: {u}")
# Using as_record decorator
@as_record()
def Product(name: str, price: float, sku=None):
pass
prod = Product("Laptop", 1200.0, "LAP001")
print(f"Product: {prod}")