Design principles: no bool arguments

Ian Kelly ian.g.kelly at gmail.com
Fri Aug 26 02:50:37 CEST 2011


On Thu, Aug 25, 2011 at 3:29 AM, Thomas 'PointedEars' Lahn
<PointedEars at web.de> wrote:
> Both variants work (even in Py3) if you only define
>
> class Data(object):
>  def merge_with(self, bar, overwrite_duplicates):
>    pass
>
> data1 = Data()
> data2 = Data()
>
> You have to define
>
> class Data(object):
>  def merge_with(self, bar, **kwargs):
>    # do something with kwargs['overwrite_duplicates']
>    pass
>
> data1 = Data()
> data2 = Data()
>
> so that
>
> data1.merge_with(data2, True);
>
> is a syntax error ("TypeError: merge_with() takes exactly 2 arguments (3
> given)").
>
> IOW, this advantage of Python in readability is not only caused by API
> definition, but also by how the API is used.  It might turn into a
> disadvantage if key lookups make the code expensive memory- and runtime
> wise.
>
> And you will still have to know the underlying signature to name the
> argument.  Worse, with keyword arguments you *have to* look up the
> documentation (i. e., it needs to be well-documented as well) to know its
> name (as the compiler can only tell you "kwargs").

Note though that Python 3 adds actual keyword-only arguments, which
address all of your points:

class Data:
    def merge_with(self, bar, *, overwrite_duplicates):
        pass

>>> data1.merge_with(data2, True)
TypeError: merge_with() takes exactly 2 positional arguments (3 given)
>>> data1.merge_with(data2)
TypeError: merge_with() needs keyword-only argument overwrite_duplicates
>>> data1.merge_with(data2, overwrite_duplicates=True)
>>>

Of course, in Python 2 that definition would be a syntax error, so you
can't really take advantage of it if you need compatibility.



More information about the Python-list mailing list