On Sat, May 11, 2019 at 1:38 PM Brendan Barnwell <brenb...@brenbarn.net>
wrote:

> > protocol for something different -- I can't image what that would be.
> > Sure, on the general case, maybe, but for a class that has a "natural"
> > use case for dictifying, how else would you want to iterate over it??
>
>         One example would be. . . dicts.  Calling dict on a dict gives you
> a
> dict, but iterating over the dict just gives you the keys.  Certain
> other mapping types (such as Pandas Series and DataFrames) also have
> this behavior where iterating over the mapping gives you only the keys.
>

well, there is that ... :-) And that IS the mapping protocol. I guess i was
thinking that you had an object that was NOT a Mapping already.

If it IS a Mapping, then presumably it already can be passed into the dict
constructor, yes?

So if you want your class "dictable", then you can implement either the
Mapping ABC, or the iteration protocol. I"m having an even harder time
imagining why you would want a Mapping interface that isn't the same as
what you'd want turned into a dict.

So why again do we yet another way to do it?

Anyway, I was playing with this, and write a prototype decorator that makes
a datacalss "dictable" -- that it, it can be passed in to the dict
constructor to make a dict. This is done by providing an iterator that
returns (key, value) pairs.

The code is in this git rep, if anyone wants to comment on it or improve,
it, or...

https://github.com/PythonCHB/PythonTopics/blob/master/Sources/code/dict_making/dictable_dataclass.py
(also here for your reading pleasure)

I'm not sure how the dict constructor decides an input is a mapping or an
iterable -- maybe I'll play with that now.

-CHB

#!/usr/bin/env python

"""
A prototype of a decorator that adds an iterator to a dataclass
so it can be passed in to the dict() constructor to make a dict.

If this is thought to be useful it could be added to the dataclass
decorator itself, to give all decorators this functionality.
"""


from dataclasses import dataclass


class DataClassIterator:
    """
    Iterator for dataclasses

    This used the class' __dataclass_fields__ dict to iterate through the
    fields and their values
    """

    def __init__(self, dataclass_instance):
        self.dataclass_instance = dataclass_instance
        self.keys_iter =
iter(dataclass_instance.__dataclass_fields__.keys())

    def __iter__(self):
        return self

    def __next__(self):
        key = next(self.keys_iter)
        return (key, getattr(self.dataclass_instance, key))


def _dunder_iter(self):
    """
    function used as the __iter__ method in the dictable_dataclass decorator
    """
    return DataClassIterator(self)


def dictable_dataclass(the_dataclass):
    """
    class decorator for making a dataclass iterable in a way that is
compatible
    with the dict() constructor
    """
    the_dataclass.__iter__ = _dunder_iter

    return the_dataclass


# Example from the dataclass docs:
@dictable_dataclass
@dataclass
class InventoryItem:
    '''Class for keeping track of an item in inventory.'''
    name: str
    unit_price: float
    quantity_on_hand: int = 0

    def total_cost(self) -> float:
        return self.unit_price * self.quantity_on_hand


if __name__ == "__main__":
    # try it out:
    inv_item = InventoryItem("sneakers", 50.0, 20)

    print("an InventoryItem:\n", inv_item)
    print()

    print("And the dict you can make from it:")
    print(dict(inv_item))











> --
> Brendan Barnwell
> "Do not follow where the path may lead.  Go, instead, where there is no
> path, and leave a trail."
>     --author unknown
> _______________________________________________
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>


-- 
Christopher Barker, PhD

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to