Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

814
Vistas
How to override names of dataclasses attributes in Python?

I am using dataclass to parse (HTTP request/response) JSON objects and today I came across a problem that requires transformation/alias attribute names within my classes.

from dataclasses import dataclass, asdict
from typing import List
import json


@dataclass
class Foo:
    foo_name: str # foo_name -> FOO NAME


@dataclass
class Bar:
    bar_name: str # bar_name -> barName


@dataclass
class Baz:
    baz_name: str # baz_name -> B A Z
    baz_foo: List[Foo] # baz_foo -> BAZ FOO
    baz_bar: List[Bar] # baz_bar -> BAZ BAR

currently:

# encode
baz_e = Baz("name", [{"foo_name": "one"}, {"foo_name": "two"}], [{"bar_name": "first"}])
json_baz_e = json.dumps(asdict(baz_e))
print(json_baz_e)
# {"baz_name": "name", "baz_foo": [{"foo_name": "one"}, {"foo_name": "two"}], "baz_bar": [{"bar_name": "first"}]}


# decode
json_baz_d = {
    "baz_name": "name", 
    "baz_foo": [{"foo_name": "one"}, {"foo_name": "two"}], 
    "baz_bar":[{"bar_name": "first"}]
}
baz_d = Baz(**json_baz_d) # back to class instance
print(baz_d)
# Baz(baz_name='name', baz_foo=[{'foo_name': 'one'}, {'foo_name': 'two'}], baz_bar=[{'bar_name': 'first'}])

expected:

# encode
baz_e = Baz("name", [{"FOO NAME": "one"}, {"FOO NAME": "two"}], [{"barName": "first"}])
json_baz_e = json.dumps(asdict(baz_e))


# decode
json_baz_d = {
    "B A Z": "name", 
    "BAZ FOO": [{"FOO NAME": "one"}, {"FOO NAME": "two"}], 
    "BAZ BAR":[{"barName": "first"}]
}
baz_d = Baz(**json_baz_d) # back to class instance

Is the only solution dataclasses-json, or is there still a possibility without additional libraries?

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

You could certainly use dataclasses-json for this, however if you don't need the advantage of marshmallow schemas, you can probably get by with an alternate solution like the dataclass-wizard, which is similarly a JSON serialization library built on top of dataclasses. It supports alias field mappings as needed here; another bonus is that it doesn't have any dependencies outside of Python stdlib, other than the typing-extensions module for Python < 3.10.

There's a few choices available to specify alias field mappings, but in the below example I chose two options to illustrate:

  • json_field, which can be considered an alias to dataclasses.field
  • a json_key_to_field mapping that can be specified in the Meta config for a dataclass
from dataclasses import dataclass
from typing import List

from dataclass_wizard import JSONWizard, json_field


@dataclass
class Foo:
    # pass all=True, so reverse mapping (field -> JSON) is also added
    foo_name: str = json_field('FOO NAME', all=True)


@dataclass
class Bar:
    # default key transform is `camelCase`, so alias is not needed here
    bar_name: str


@dataclass
class Baz(JSONWizard):

    class _(JSONWizard.Meta):
        json_key_to_field = {
            # Pass '__all__', so reverse mapping (field -> JSON) is also added
            '__all__': True,
            'B A Z': 'baz_name',
            'BAZ FOO': 'baz_foo',
            'BAZ BAR': 'baz_bar'
        }

    baz_name: str
    baz_foo: List[Foo]
    baz_bar: List[Bar]


# encode
baz_e = Baz("name", [Foo('one'), Foo('two')], [Bar('first')])
json_baz_d = baz_e.to_dict()

print(json_baz_d)
# {'B A Z': 'name', 'BAZ FOO': [{'FOO NAME': 'one'}, {'FOO NAME': 'two'}], 'BAZ BAR': [{'barName': 'first'}]}

# decode
baz_d = Baz.from_dict(json_baz_d)  # back to class instance

print(repr(baz_d))
# > Baz(baz_name='name', baz_foo=[Foo(foo_name='one'), Foo(foo_name='two')], baz_bar=[Bar(bar_name='first')])

# True
assert baz_e == baz_d

NB: I noticed one obvious thing that I wanted to point out, as it seemed to not result in expected behavior. In the question above, you appear to be instantiating a Baz instance as follows:

baz_e = Baz("name", [{"foo_name": "one"}, {"foo_name": "two"}], [{"bar_name": "first"}])

However, note that the value for the baz_foo field, in this case, is a list of Python dict objects rather than a list of Foo instances. To fix this, in above solution I've changed the {"foo_name": "one"} for example to Foo('one').

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda