Message383897
I have use cases in which I use named tuples to represent data sets, e.g:
class BasicStats(NamedTuple):
"""Basic statistics response packet."""
type: Type
session_id: BigEndianSignedInt32
motd: str
game_type: str
map: str
num_players: int
max_players: int
host_port: int
host_ip: IPAddressOrHostname
I want them to behave as intended, i.e. that unpacking them should behave as expected from a tuple:
type, session_id, motd, … = BasicStats(…)
I also want to be able to serialize them to a JSON-ish dict.
The NamedTuple has an _asdict method, that I could use.
json = BasicStats(…)._asdict()
But for the dict to be passed to JSON, I need customization of the dict representation, e.g. set host_ip to str(self.host_ip), since it might be a non-serializable ipaddress.IPv{4,6}Address. Doing this in an object hook of json.dumps() is a non-starter, since I cannot force the user to remember, which types need to be converted on the several data structures.
Also, using _asdict() seems strange as an exposed API, since it's an underscore method and users hence might not be inclined to use it.
So what I did is to add a method to_json() to convert the named tuple into a JSON-ish dict:
def to_json(self) -> dict:
"""Returns a JSON-ish dict."""
return {
'type': self.type.value,
'session_id': self.session_id,
'motd': self.motd,
'game_type': self.game_type,
'map': self.map,
'num_players': self.num_players,
'max_players': self.max_players,
'host_port': self.host_port,
'host_ip': str(self.host_ip)
}
It would be nicer to have my type just return this appropriate dict when invoking dict(BasicStats(…)). This would require me to override the __iter__() method to yield key / value tuples for the dict.
However, this would break the natural behaviour of tuple unpacking as described above.
Hence, I propose to add a method __iter_items__(self) to the python data model with the following properties:
1) __iter_items__ is expected to return an iterator of 2-tuples representing key / value pairs.
2) the built-in function dict(), when called on an object, will attempt to create the object from __iter_items__ first and fall back to __iter__.
Alternative names could also be __items__ or __iter_dict__. |
|
Date |
User |
Action |
Args |
2020-12-28 15:26:40 | conqp | set | recipients:
+ conqp |
2020-12-28 15:26:40 | conqp | set | messageid: <1609169200.88.0.326770807054.issue42765@roundup.psfhosted.org> |
2020-12-28 15:26:40 | conqp | link | issue42765 messages |
2020-12-28 15:26:40 | conqp | create | |
|