On Tue, May 3, 2022 at 6:36 AM Paul Moore <p.f.mo...@gmail.com> wrote:
> On Tue, 3 May 2022 at 03:04, Steven D'Aprano <st...@pearwood.info> wrote: > > > > On Mon, May 02, 2022 at 07:44:14PM +0100, Paul Moore wrote: > > > > > I have classes with 20+ parameters (packaging metadata). You can argue > > > that a dataclass would be better, or some other form of refactoring, > > > and you may actually be right. But it is a legitimate design for that > > > use case. > > > > Indeed. 20+ parameters is only a code smell, it's not *necessarily* > > wrong. Sometimes you just need lots of parameters, even if it is ugly. > > > > For reference, open() only takes 8, so 20 is a pretty wiffy code smell, > > but it is what it is. > > It's worth noting that dataclasses with lots of attributes by default > generate constructors that require all of those as parameters. So it's > a code smell yes, but by that logic so are dataclasses with many > attributes (unless you write a bunch of custom code). Genuine question > - what *is* a non-smelly way of writing a dataclass with 24 > attributes? > > I've written about 20 variations on this particular class so far, and > none of them feel "right" to me :-( > > > > Of course the real problem is that you often don't want to > > > *quite* assign the argument unchanged - `self.provides_extras = > > > set(provides_extras or [])` or `self.requires_python = requires_python > > > or specifiers.SpecifierSet()` are variations that break the whole > > > "just assign the argument unchanged" pattern. > > > > Indeed. Once we move out of that unchanged assignment pattern, we need > > to read more carefully rather than skim > > > > self._spam = (spam or '').lower().strip() > > > > but you can't replace that with auto assignment. > > Precisely. > > > > As a variation on the issue, which the @ syntax *wouldn't* solve, in > > > classmethods for classes like this, I often find myself constructing > > > dictionaries of arguments, copying multiple values from one dict to > > > another, sometimes with the same sort of subtle variation as above: > > > > > > @classmethod > > > def from_other_args(cls, a, b, c, d): > > > kw = {} > > > kw["a"] = a > > > kw["b"] = b > > > kw["c"] = c > > > kw["d"] = d > > > return cls(**kw) > > > > You may find it easier to make a copy of locals() and delete the > > parameters you don't want, rather than retype them all like that: > > > > params = locals().copy() > > for name in ['cls', 'e', 'g']: > > del params[name] > > return cls(**params) > > > > > > > Again, in "real code", not all of these would be copied, or some would > > > have defaults, etc. The pattern's the same, though - enough args > > > arecopied to make the idea of marking them with an @ seem attractive. > > > > But the @ proposal here won't help. If you mark them with @, won't they > > be auto-assigned onto cls? > > Again, precisely. > > My point here is that the @ proposal is, in my experience, useful in > far fewer situations than people are claiming. What *is* common (again > in my experience) is variations on a pattern that can be described as > "lots of repetitive copying of values from one location to another, > possibly with minor modifications". Having a way of addressing the > broader problem *might* be of sufficient use to be worth pursuing, and > it might even be possible to do something useful in a library, not > needing new syntax. > It's a good point. We have been thinking a bit about how to measure the "usefulness" of the proposal. What we have so far is mainly an intuition driven by code that we and colleagues developed and a couple of statistics ( https://github.com/quimeyps/analize_autoassign in case anyone reading this doesn't have the link nearby). Although I think that code analysis can be a way to find out the usefulness of the proposal, the statistics that we have so far feel a bit coarse-grained to be honest. So any idea on what would be good metrics to answer the question of "how ofthen the syntax would be useful" will be more than welcome! > > On the other hand, the @ syntax as proposed *doesn't* address enough > use cases (for me!) to be worthwhile, especially not if new syntax is > needed rather than just something like a decorator. > > Paul > _______________________________________________ > Python-ideas mailing list -- python-ideas@python.org > To unsubscribe send an email to python-ideas-le...@python.org > https://mail.python.org/mailman3/lists/python-ideas.python.org/ > Message archived at > https://mail.python.org/archives/list/python-ideas@python.org/message/CD3HRBE2Q6WIKOJDE5GCLFVVHMGR42VZ/ > Code of Conduct: http://python.org/psf/codeofconduct/ >
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/VDOIDOI7F23UOQ67O3F7ME4SVC5JUBUV/ Code of Conduct: http://python.org/psf/codeofconduct/