On Mon, 15 May 2017 at 10:32 Guido van Rossum <gu...@python.org> wrote:
> On Mon, May 15, 2017 at 9:50 AM, Brett Cannon <br...@python.org> wrote: > >> >> On Mon, 15 May 2017 at 08:30 Guido van Rossum <gu...@python.org> wrote: >> >>> This should be worked into a PEP, instead of living on as a bunch of >>> python-ideas posts and blogs. >>> >>> I find the attrs documentation (and Glyph's blog post about it) almost >>> unreadable because of the exalted language -- half the doc seems to be >>> *selling* the library more than *explaining* it. If this style were to >>> become common I would find it a disturbing trend. >>> >>> But having something alongside NamedTuple that helps you declare classes >>> with mutable attributes using the new PEP 526 syntax (and maybe a few >>> variants) would definitely be useful. Will someone please write a PEP? Very >>> few of the specifics of attrs need be retained (its punny naming choices >>> are too much for the stdlib). >>> >> >> In case someone decides to take this on, I wrote a blog post back in >> March that shows how to use __init_subclass__() to do a rough approximation >> of what Guido is suggesting: >> https://snarky.ca/customizing-class-creation-in-python/ . >> >> Based on my thinking on the topic while writing my blog post, the tricky >> bit is going to be deciding how to handle default values (i.e. if you set a >> default value like `attr: int = 42` on the class definition then you have >> `cls.attr` exist which might not be what you want if you would rather have >> the default value explicitly set on every instance but not fall through to >> the class (e.g. `del ins.attr; ins.attr` raises an AttributeError instead >> of falling through to `cls.attr`). You could remove the default from the >> class in your __init_subclass__(), but then you have to decide if that's >> too unexpected/magical for someone looking at the code. >> > > I would personally prefer the initializer to stay in the class in cases > like this. If the initializer needs to be a default instance of a mutable > class (e.g. an empty list or dict) there could be a special marker to > indicate that, e.g. > > attacks: List[int] = MAKE_NEW # Creates a new [] for each instance > > while if the default needs to be something more custom it could be a > similar marker with a callable argument, e.g. > > fleet: Dict[str, str] = MAKE_NEW(lambda: {'flagship': 'Enterprise'}) > > I would prefer not to have cleverness like initialization with a callable > automatically does something different. > So if I'm understanding your idea correctly: class Foo(DataClass): attr: int = 42 would leave Foo.attr alone, but: class Foo(DataClass): attr: int = MAKE_NEW(42) would be the way to flag that `Foo.attr` shouldn't exist (I'm assuming both options would flag that there should be an `attr` argument to __init__())? > > >> And I too would be interested in seeing something like this, if for any >> other reason than to help people not to misuse NamedTuple for >> quick-and-dirty data objects in new APIs (NamedTuple is meant to help move >> old-style tuple-based APIs to a class-based one). >> > > Not sure I agree that is its only purpose. > My typical thinking on this is I don't want the tuple API that comes with NamedTuple for new APIs, and so that's when I reach for types.SimpleNamespace and have a function that controls the constructor so I can provide a concrete initializer API (e.g. `def foo(a, b): return types.SimpleNamespace(a=a, b=b)`). -Brett > > -- > --Guido van Rossum (python.org/~guido) >
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/