On Mon, 4 May 2020 at 19:13, Lewis Ball <lrjb...@gmail.com> wrote:
>
> I had a similar solution with a decorator using inspect.getfullargspec but it 
> is pretty fiddly and it is pretty easy to miss
>  some of the edge cases. Having a standard implementation would definitely 
> take care of this. And I imagine
> static analysis tools would be able to cope with it, they do a good job with 
> all of the current language features!

I like this idea of having a decorator for that.
Since the decorator can apply the arguments to the instance without
actually fiddling into `locals` or on `__init__`
code.

It could also be used _with_ dataclasses, suplying the assignment boiler
plate for when one wants to have an explicit __init__ method.
(yes, there is post_init, but as seem recently in a thread here, it is
tough to get it
working cooperatively)

But I suppose

@autoassign
def __init__(self, a, b, flag1, flag2, etcetera):
      ...

could live in "functools" without causing great harm.



>
> On Mon, 4 May 2020, 22:11 Steele Farnsworth, <swfarnswo...@gmail.com> wrote:
>>
>> I agree that dataclasses are for a slightly different use case.
>>
>> It looks like this could be implemented as a decorator using the 
>> functionality afforded by `inspect.signature`, though what I've come up with 
>> so far is a bit clunky because you have to account for parameters that could 
>> be positional or keyword and assigning default values for missing arguments.
>>
>> If this were added, I assume that static analysis tools would need to be 
>> updated to account for the assumption that each instance has attributes with 
>> the same names that appear in the `__init__` signature, and I have no idea 
>> what that would entail. It would probably pose a similar issue for automated 
>> refactoring.
>>
>> On Mon, May 4, 2020 at 4:48 PM Lewis Ball <lrjb...@gmail.com> wrote:
>>>
>>> I did think about data classes and although I haven't really used them much 
>>> they do seem to be for a different use case, for example they don't support 
>>> keyword-only args or positional-only args. I'm not sure if there are any 
>>> other differences. Maybe a data class which supported kW-only args and 
>>> pos-only args would suit my use case.
>>>
>>> On Mon, 4 May 2020, 21:19 Henk-Jaap Wagenaar, <wagenaarhenkj...@gmail.com> 
>>> wrote:
>>>>
>>>> You are not the first to have this idea. Unless I am mistaken you might 
>>>> find what you are looking for in dataclasses which were added in Python 
>>>> 3.7:
>>>>
>>>> https://docs.python.org/3/library/dataclasses.html
>>>>
>>>> On Mon, 4 May 2020 at 19:06, Lewis Ball <lrjb...@gmail.com> wrote:
>>>>>
>>>>> Hi All,
>>>>>
>>>>> First of all, if this is something which has been discussed in the past 
>>>>> the please point me in the right direction.
>>>>>
>>>>> Problem:
>>>>>
>>>>> When creating classes in Python, I find myself writing the __init__ 
>>>>> method in a very similar way a lot of the time, that is:
>>>>> ```
>>>>> def __init__(self, argument_1, argument_2, argument_3=None):
>>>>>     self.argument_1 = argument_1
>>>>>     self.argument_2 = argument_2
>>>>>     self.argument_3 = argument_3
>>>>>     # then maybe some other attribute setting and logic follows
>>>>> ```
>>>>>
>>>>> Every argument of __init__ gets a corresponding attribute with the same 
>>>>> name. This means that each `argument_i` has been typed 3 times, which 
>>>>> seems overly-verbose as well as being easy to mistype. This pattern is 
>>>>> easy to find in various popular python libraries, and in some it is 
>>>>> actually enforced. For example, I do quite a bit of work with classifiers 
>>>>> using the sklearn estimator API, and for various reasons sklearn enforce 
>>>>> this pattern for an __init__ (see here if interested).
>>>>>
>>>>> Here is an example of this pattern from the standard library (from 
>>>>> textwrap.TextWrapper):
>>>>> ```
>>>>> def __init__(self,
>>>>>          width=70,
>>>>>          initial_indent="",
>>>>>          subsequent_indent="",
>>>>>          expand_tabs=True,
>>>>>          replace_whitespace=True,
>>>>>          fix_sentence_endings=False,
>>>>>          break_long_words=True,
>>>>>          drop_whitespace=True,
>>>>>          break_on_hyphens=True,
>>>>>          tabsize=8,
>>>>>          *,
>>>>>          max_lines=None,
>>>>>          placeholder=' [...]'):
>>>>> self.width = width
>>>>> self.initial_indent = initial_indent
>>>>> self.subsequent_indent = subsequent_indent
>>>>> self.expand_tabs = expand_tabs
>>>>> self.replace_whitespace = replace_whitespace
>>>>> self.fix_sentence_endings = fix_sentence_endings
>>>>> self.break_long_words = break_long_words
>>>>> self.drop_whitespace = drop_whitespace
>>>>> self.break_on_hyphens = break_on_hyphens
>>>>> self.tabsize = tabsize
>>>>> self.max_lines = max_lines
>>>>> self.placeholder = placeholder
>>>>> ```
>>>>>
>>>>> With a quick scan of the top 50 or so most used python packages, 1 in 4 
>>>>> __init__ methods that takes arguments has the line `self.argument_i = 
>>>>> argument_i` for every single argument, with several of them having 10+ 
>>>>> arguments.
>>>>>
>>>>> Suggestion:
>>>>>
>>>>> A new built-in called something like `assign()` which would assign every 
>>>>> single __init__ arg to a corresponding attribute. e.g. the snippet from 
>>>>> above could be rewritten to:
>>>>> ```
>>>>> def __init__(self, argument_1, argument_2, argument_3=None):
>>>>>     assign()
>>>>>     # other init logic goes here
>>>>> ```
>>>>>
>>>>> This could alternatively be implemented as a decorator, like so
>>>>> ```
>>>>> @assign
>>>>> def __init__(self, argument_1, argument_2, argument_3=None):
>>>>>     # other init logic goes here
>>>>> ```
>>>>> but then this requires a `pass` if no other logic is needed inside the 
>>>>> __init__. There may also be some other syntax for this which would be 
>>>>> even easier to use.
>>>>>
>>>>> Is this something that others would find useful?
>>>>>
>>>>> Thanks,
>>>>>
>>>>> Lewis
>>>>> _______________________________________________
>>>>> 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/VLI3DOFA5VWMGJMJGRDC7JZTRKEPPZNU/
>>>>> 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/SCTXSEKOWDRDGVXXOEB7JUC6WE7XKGMO/
>>> 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/3QY6NIT7Y37PHKCYGJXJAONS35E3YZWH/
>> 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/4SQF4E3XWQ4XKAS3DMTNYJYJBZEUQIKC/
> 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/6F26QAI7ZOU42FSUHJO3MMBXSY5DY5EU/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to