DynamicClassAttribute: Descriptors and Dynamic Access

Published on: August 30, 2026
Reading time: 2 minutes
Detailed close-up of yellow and white albino python scales, capturing texture and pattern.

types.DynamicClassAttribute is a specialized descriptor that behaves like a property on instances while allowing class-level access to be routed through the class’s metaclass __getattr__. This unusual behavior supports APIs where the same name needs different meanings on an instance and on the class.

The best-known use is related to Enum. Before using it directly, understand descriptors, properties, and metaclasses.

Basic behavior

from types import DynamicClassAttribute

class Item:
    def __init__(self, value):
        self._value = value

    @DynamicClassAttribute
    def value(self):
        return self._value

print(Item(10).value)

On an instance, the descriptor behaves similarly to property.

Class-level access

When Item.value is requested, the descriptor raises AttributeError. A metaclass can then answer through __getattr__.

class Meta(type):
    def __getattr__(cls, name):
        if name == "value":
            return "class-level value"
        raise AttributeError(name)

class Item(metaclass=Meta):
    @DynamicClassAttribute
    def value(self):
        return 42

print(Item().value)
print(Item.value)

Difference from property

A normal property accessed on the class usually returns the descriptor object. DynamicClassAttribute intentionally triggers the missing-attribute path at class level.

Descriptor protocol

Descriptors control access through __get__, __set__, and __delete__. Like property, this class supports getter, setter, and deleter methods.

Metaclass requirement

The dynamic class-level behavior requires __getattr__ on the metaclass. Defining an instance method named __getattr__ on the regular class does not handle missing attributes of the class object itself.

Why Enum needs this idea

Enum implementations distinguish member lookup, instance attributes, and names resolved on the enum class. A dynamic class attribute helps keep those namespaces separate.

Good use cases

  • Frameworks with metaclass-managed namespaces.
  • APIs with intentionally different class and instance semantics.
  • Enum-like type systems.
  • Advanced proxy and introspection infrastructure.

When to avoid it

Most applications are clearer with different names or explicit class methods. Dynamic resolution complicates autocomplete, documentation, static analysis, and debugging.

Static introspection

Normal getattr can execute dynamic lookup. Use inspect.getattr_static or inspect.getmembers_static to inspect the descriptor without invoking it.

import inspect

descriptor = inspect.getattr_static(Item, "value")
print(type(descriptor))

Typing concerns

Type checkers may not model metaclass-generated names perfectly. Keep public APIs simple and consider stubs, protocols, or overloads.

Common mistakes

  • Placing __getattr__ on the class instead of the metaclass.
  • Expecting class access to return the descriptor.
  • Creating recursion inside dynamic lookup.
  • Using it where a normal property is sufficient.
  • Ignoring documentation and introspection behavior.

Limit this feature to infrastructure code, test both access paths, preserve useful AttributeError messages, and document the dual meaning. See the internal guides to the types module, Enums, and introspection.

Conclusion

DynamicClassAttribute combines instance-property behavior with dynamic class-level resolution. It is powerful for metaclass frameworks but should be used sparingly.

External sources

Share:

Facebook
WhatsApp
Twitter
LinkedIn

Article content

    Related articles

    Python code on a laptop for creating dynamic dataclasses
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    make_dataclass decorator: Transform Dataclasses

    Learn how the make_dataclass decorator parameter validates, registers, and transforms dynamic dataclasses safely in Python.

    Ler mais

    Tempo de leitura: 5 minutos
    23/10/2026
    Code and XML structure for canonicalization with Python
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    ElementTree canonicalize: Normalize XML in Python

    Learn Python ElementTree canonicalize for stable XML comparisons, hashes, namespaces, comments, and signature preparation.

    Ler mais

    Tempo de leitura: 5 minutos
    22/10/2026
    Python programming code displayed on a screen
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    T-strings and templatelib: Structured Interpolation

    Learn Python t-strings and string.templatelib for structured interpolation, safer renderers, logging, and custom processing.

    Ler mais

    Tempo de leitura: 5 minutos
    22/10/2026
    SQLite database and Python code for selective iterdump export
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    SQLite iterdump: Create Selective Dumps in Python

    Learn sqlite3.Connection.iterdump filters for selective SQLite dumps, dependency checks, validation, and safer restoration.

    Ler mais

    Tempo de leitura: 4 minutos
    21/10/2026
    Code and files representing Python data compression
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    compression.zstd: Fast Zstandard in Python

    Learn Python compression.zstd for fast file and data compression, streaming, integrity checks, and safe decompression.

    Ler mais

    Tempo de leitura: 7 minutos
    21/10/2026
    Configuration file and code structure for Python ConfigParser
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    ConfigParser: Read INI Files Without Sections

    Learn Python ConfigParser unnamed sections with validation, typed values, compatibility, layered settings, and safe INI writing.

    Ler mais

    Tempo de leitura: 5 minutos
    20/10/2026