Encapsulation in Python

Chris Angelico rosuav at gmail.com
Mon Mar 14 20:12:26 EDT 2016


On Tue, Mar 15, 2016 at 10:56 AM, BartC <bc at freeuk.com> wrote:
> I disagree. And presumably so do others as there are so many different
> attempts to implement switch, with varying degrees of success. Here's how I
> do it outside Python:
>
>  switch c
>  when 'A'..'Z','a'..'z','_' then
>      ++name
>  when '0'..'9' then
>      ++numeric
>  when "()[]<>{}" then
>      ++brackets
>  else
>      ++other
>  end
>
> Anything so terrible about that that Python needs to keep well clear of or
> that you think its users should be deprived of?

Yes: the complete lack of colons at the ends of lines that introduce
suites. This is utterly unacceptable in Python!

Seriously though - the one thing that I'm very concerned about here is
your brackets one. In Python, there's no reason to restrict 'switch'
to integers, so I would expect its semantics to be based on either
equality comparisons or inequality comparisons (possibly with a
requirement that all values be hashable); you could have something
like "when in <string>" but a simple "when <string>" would look to me
like it's testing for that entire string. (Don't forget that, in
Python, there's no difference between 'single quoted strings' and
"double quoted strings", as there is in C-like languages.)

Although... come to think of it, you could actually define it the
other way around: the 'when' statement checks if the current switch
object is contained within any of its arguments. Coupled with a
range-like object with its own literal syntax, that would pretty much
give you what you're looking at there. However, you'd need to have an
awkward notation for the cases where you _are_ looking for equality:

switch c:
    when 'A'..'Z', 'a'..'z', ['_']:
        ++name

Or, in a long tree:

switch c:
    when [1]:
        ...
    when [2]:
        ...
    when [3]:
        ...

Which could work. It'd be well-defined, and not unreasonable. It
would, however, be entirely predicated on a "comparison range" object
with a literal syntax:

class Range:
    def __init__(self, start, stop):
        self.start = start
        self.stop = stop
    def __contains__(self, obj):
        return self.start <= obj <= self.stop
    def __repr__(self):
        return "%r..%r" % (self.start, self.stop)

But that's not overly hard either.

ChrisA



More information about the Python-list mailing list