Encapsulation in Python

BartC bc at freeuk.com
Mon Mar 14 20:54:40 EDT 2016


On 15/03/2016 00:12, Chris Angelico wrote:
> On Tue, Mar 15, 2016 at 10:56 AM, BartC <bc at freeuk.com> wrote:

>>   switch c
>>   when 'A'..'Z','a'..'z','_' then
>>       ++name

>> 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.

Yeah, I'm not sure about that either. I'd already written:

  when '(', ')', ....

when I thought having a string constant here would be neat, and 
implemented that just before posting.

> 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

I use two forms of switch: one for integers only (very fast), and the 
other for any other values, which does tests in sequence.

> (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.

The tests I do for the more general switch are either equality, or 'in' 
for certain combinations of types (mainly testing integers for 
membership of ranges and sets. Sets are Pascal-style bit-sets).

I've also looked at the problem of when the choice might be ambiguous:

case x             # general 'switch'
when y then
...

What happens when y is a list; should it do x==y or x in y? (Or both?)

I haven't solved that yet but it's never come up. When x is anything 
other than an int, you invariably want an equality test.

-- 
Bartc



More information about the Python-list mailing list