Home > Net >  How can I specify order of data in Attrs?
How can I specify order of data in Attrs?

Time:08-10

Taking from attrs example here but adding group_id. I want to create data classes so I can then export them to JSON using json.dump().

@define
class User:
    email: str
    password: str

@define
class UserList:
    users: list[User]
    group_id: str = field(default=str(uuid4()), on_setattr=frozen)

json.dump(asdict(UserList([User("[email protected]", "s33kred"),
                 User("[email protected]", "p4ssw0rd")]),
       filter=lambda attr, value: attr.name != "password"))

That prints out this:

{"users": [{"email": "[email protected]"}, {"email": "[email protected]"}], "group-id": "a9fc0c10-125f-4c65-a901-ac16e3b57bc7"}

However, my issue is that I want group-id to be at the very top, like this:

{"group-id": "a9fc0c10-125f-4c65-a901-ac16e3b57bc7", "users": [{"email": "[email protected]"}, {"email": "[email protected]"}]}

It seems that attrs organise them on initialisation and because group-id has a default value, I am unable to place it at the top.

Any thoughts on how to solve this issue?

CodePudding user response:

Which Python version? As of Python 3.7 dictionaries are insertion ordered so asdict should respect the order of the fields as you provided them.

You could also change the dict_factory arg of attr.asdict to use collections.OrderedDict to enforce this otherwise.

CodePudding user response:

Do you want to sort your keys in the end? You can do it by passing sort_keys=True. For example:

import json
print(
    json.dumps(
        {"users": [
            {"email": "[email protected]"},
            {"email": "[email protected]"}
        ],
            "group-id": "a9fc0c10-125f-4c65-a901-ac16e3b57bc7"},
        sort_keys=True
    )
)

Output:

{"group-id": "a9fc0c10-125f-4c65-a901-ac16e3b57bc7", "users": [{"email": "[email protected]"}, {"email": "[email protected]"}]}
  • Related