How can we best switch in python?
Содержание:
- Python Switch Case Statement
- 4.8. Intermezzo: Coding Style¶
- 4.4. break and continue Statements, and else Clauses on Loops¶
- A Concrete Example
- Boolean Logic#
- Why not use a sublocal scope and prevent namespace pollution?
- Descriptive: Naming Styles
- Are you tired of writing too many if…elif…else statements when you want to “switch” in Python?
- Отличия цикла for в Python от других языков
- Boolean Contexts#
- Моя часть
- Python Switch Case Statement
- Реализация цикла for с помощью функции и цикла while
- Non-Boolean Contexts#
- Discussion
- 4.2. for Statements¶
- 4.6. Defining Functions¶
- Solutions for Python Switch Case Statement
- Спецификация изменяется во время реализации
- A numeric example
- Relative precedence of :=
- Why not just raw dict?
- Зачем нужны условные инструкции
- Source File Encoding
Python Switch Case Statement
Unlike other programming languages, Python doesn’t provide a switch case instrument over the self.
However, it has many other constructs like a dictionary, lambda function, and classes to write a custom implementation of the Python switch case statement.
If you are keen to know why Python doesn’t have a switch case, then do refer the explanation at PEP 3103.
Before diving into further, let’s have a quick view of the most common example of a switch case statement in the C programming language.
A Typical Switch Case in C Programming
- In C, you can only pass an integer or enum value to the switch-case statement.
- Unlike the if…else block which requires evaluating expressions in each condition, the switch has a single point of interaction which leads to different paths of execution.
- A switch is a control instruction which decides the control to flow based on the value of a variable or an expression.
In the below example, the variable ‘dayOfWeek’ is a constant integer variable which represents days in a week. And the switch-case block prints the name of the day based on its value.
switch (dayOfWeek) { case 1: printf("%s", Monday); break; case 2: printf("%s", Tuesday); break; case 3: printf("%s", Wednesday); break; case 4: printf("%s", Thursday); break; case 5: printf("%s", Friday); break; case 6: printf("%s", Saturday); break; case 7: printf("%s", Sunday); break; default: printf("Incorrect day"); break; }
There are a couple of facts to consider for the switch-case statement.
- The expression under the switch gets evaluated once.
- It should result in a constant integer value.
- A case with a duplicate value should not appear.
- If no case matches, then the default case gets executed.
4.8. Intermezzo: Coding Style¶
Now that you are about to write longer, more complex pieces of Python, it is a
good time to talk about coding style. Most languages can be written (or more
concise, formatted) in different styles; some are more readable than others.
Making it easy for others to read your code is always a good idea, and adopting
a nice coding style helps tremendously for that.
For Python, PEP 8 has emerged as the style guide that most projects adhere to;
it promotes a very readable and eye-pleasing coding style. Every Python
developer should read it at some point; here are the most important points
extracted for you:
-
Use 4-space indentation, and no tabs.
4 spaces are a good compromise between small indentation (allows greater
nesting depth) and large indentation (easier to read). Tabs introduce
confusion, and are best left out. -
Wrap lines so that they don’t exceed 79 characters.
This helps users with small displays and makes it possible to have several
code files side-by-side on larger displays. -
Use blank lines to separate functions and classes, and larger blocks of
code inside functions. -
When possible, put comments on a line of their own.
-
Use docstrings.
-
Use spaces around operators and after commas, but not directly inside
bracketing constructs: . -
Name your classes and functions consistently; the convention is to use
for classes and for functions
and methods. Always use as the name for the first method argument
(see for more on classes and methods). -
Don’t use fancy encodings if your code is meant to be used in international
environments. Python’s default, UTF-8, or even plain ASCII work best in any
case. -
Likewise, don’t use non-ASCII characters in identifiers if there is only the
slightest chance people speaking a different language will read or maintain
the code.
Footnotes
-
Actually, call by object reference would be a better description,
since if a mutable object is passed, the caller will see any changes the
callee makes to it (items inserted into a list).
4.4. break and continue Statements, and else Clauses on Loops¶
The statement, like in C, breaks out of the innermost enclosing
or loop.
Loop statements may have an clause; it is executed when the loop
terminates through exhaustion of the iterable (with ) or when the
condition becomes false (with ), but not when the loop is
terminated by a statement. This is exemplified by the
following loop, which searches for prime numbers:
>>> for n in range(2, 10): ... for x in range(2, n): ... if n % x == ... print(n, 'equals', x, '*', n//x) ... break ... else ... # loop fell through without finding a factor ... print(n, 'is a prime number') ... 2 is a prime number 3 is a prime number 4 equals 2 * 2 5 is a prime number 6 equals 2 * 3 7 is a prime number 8 equals 2 * 4 9 equals 3 * 3
(Yes, this is the correct code. Look closely: the clause belongs to
the loop, not the statement.)
When used with a loop, the clause has more in common with the
clause of a statement than it does with that of
statements: a statement’s clause runs
when no exception occurs, and a loop’s clause runs when no
occurs. For more on the statement and exceptions, see
.
The statement, also borrowed from C, continues with the next
iteration of the loop:
A Concrete Example
Let’s assume we want to write a program to read the owner of files/directories (on a Unix system) in our current directory and print them on screen.
Does everything work correctly? Apparently it does. We specified the encoding for the file containing the source code, if we have a file created by олга (uid 1001) in our directory its name will be printed correctly, and even if we have files with non-ASCII names these will be printed correctly.
There’s still a case that we haven’t covered yet though: a file created by олга AND with non-ASCII characters in the name…
Let’s try to launch again our small script, and we’ll obtain a:
If you think about it, a similar situation could be nasty: You have written your program (thousands of lines long instead of the few 4 of this example), you start to gather some users, some of them even from non-English speaking countries with more exotic names. Everything is okay, until one of these users decides to create a file that users with more prosaic name can create without any problem. Now your code will throw an error, the server might answer every request from this user with a error 500, and you’ll need to dig in the codebase to understand why suddenly these errors are appearing.
How does Python 3 help us with this? If you try to execute the same script, you’ll discover that Python is able to detect right away when you’re about to execute a dangerous operation. Even without files with peculiar names and/or created by peculiar users, you’ll receive right away an exception like:
Related to line:
The error message is even more easy to understand, in my opinion. The str object is , and is a bytes object. Knowing this, it’s obvious that the problem is due to the fact that is returning us a list of bytes objects.
A detail that not everybody knows is that returns a list of bytes objects or unicode strings depending on the type of the object that was used as input. I avoided using exactly to obtain the same behavior on Python 2 and Python 3, otherwise on Python 3 this would’ve been an unicode string that would’ve made the bug disappear.
If we try to change a single character, from to we’ll be able to see how the code now works on both Python 3 and Python 2. For completeness, we should also change to .
This difference in the behavior between Python 2 and Python 3 is however supported by a radical difference in how the two versions handle string types, a difference that is mainly perceived when porting from one version to the other.
In my opinion, this situation is emblematic of the maxim: “splitters can be lumped more easily than lumpers can be split”. What was lumped together in Python 2 (unicode strings and default strings of byte, which could be freely coerced together) has been split in Python 3.
Boolean Logic#
George Boole (1815–1864) developed what is now called Boolean algebra, which is the foundation of the digital logic behind computer hardware and programming languages.
Boolean algebra is built around the truth value of expressions and objects (whether they are true or false) and is based in the Boolean operations , , and . These operations are implemented through logical or Boolean operators that allow you to create Boolean expressions, which are expressions that evaluate to true or false.
With the help of Boolean logic, you can evaluate conditions and decide what operations your programs will execute, depending on the truth value of those conditions. This is an important cornerstone in programming and provides you with the tools to decide the execution flow of your programs.
Let’s take a look at some of the basic concepts related to Boolean logic in Python:
-
Boolean is type of value that can be either or . In Python, the Boolean type is , which is a subtype of .
-
Boolean values are the values or (with a capital T and F) in Python.
-
A Boolean variable is a variable that can be either or . Boolean variables are commonly used as to indicate whether specific conditions exist.
-
A Boolean expression is an expression that returns either or .
-
Boolean context can be conditions and loops, where Python expects an expression to evaluate to a Boolean value. You can use virtually any expression or object in a Boolean context, and Python will try to determine its truth value.
-
Operands are the subexpressions or objects involved in an expression (Boolean or not) and connected by an operator.
-
Boolean or logical operators are (logical or conjunction), (logical or disjunction), and (logical or negation). The keywords , , and are the Python operators for these operations.
Why not use a sublocal scope and prevent namespace pollution?
Previous revisions of this proposal involved sublocal scope (restricted to a
single statement), preventing name leakage and namespace pollution. While a
definite advantage in a number of situations, this increases complexity in
many others, and the costs are not justified by the benefits. In the interests
of language simplicity, the name bindings created here are exactly equivalent
to any other name bindings, including that usage at class or module scope will
create externally-visible names. This is no different from for loops or
other constructs, and can be solved the same way: del the name once it is
no longer needed, or prefix it with an underscore.
Descriptive: Naming Styles
There are a lot of different naming styles. It helps to be able to
recognize what naming style is being used, independently from what
they are used for.
The following naming styles are commonly distinguished:
-
b (single lowercase letter)
-
B (single uppercase letter)
-
lowercase
-
lower_case_with_underscores
-
UPPERCASE
-
UPPER_CASE_WITH_UNDERSCORES
-
CapitalizedWords (or CapWords, or CamelCase — so named because
of the bumpy look of its letters ). This is also sometimes known
as StudlyCaps.Note: When using acronyms in CapWords, capitalize all the
letters of the acronym. Thus HTTPServerError is better than
HttpServerError. -
mixedCase (differs from CapitalizedWords by initial lowercase
character!) -
Capitalized_Words_With_Underscores (ugly!)
There’s also the style of using a short unique prefix to group related
names together. This is not used much in Python, but it is mentioned
for completeness. For example, the os.stat() function returns a
tuple whose items traditionally have names like st_mode,
st_size, st_mtime and so on. (This is done to emphasize the
correspondence with the fields of the POSIX system call struct, which
helps programmers familiar with that.)
The X11 library uses a leading X for all its public functions. In
Python, this style is generally deemed unnecessary because attribute
and method names are prefixed with an object, and function names are
prefixed with a module name.
In addition, the following special forms using leading or trailing
underscores are recognized (these can generally be combined with any
case convention):
Are you tired of writing too many if…elif…else statements when you want to “switch” in Python?
Yong Cui, Ph.D.Follow
Feb 3 · 6 min read
Unlike most programming languages, Python doesn’t have a built-in implementation of a switch statement. In general, a switch statement is to evaluate an expression or a variable against a list of values to check for equality. When the case matches the evaluation result or the variable, the corresponding operations will run under that case. When no case is found, the default operations will run instead.
Here’s an example of a switch statement in Swift. When we call this function with different characters, the operations for the matched case or the default run as expected.
Given no switch statements in Python, the present article is to show you how we can implement a switch-like functionality in Python. Specifically, the article consists of the following two parts, as implied by the article’s title.
Отличия цикла for в Python от других языков
Стоит отдельно остановиться на том, что цикл , в Python, устроен несколько иначе, чем в большинстве других языков. Он больше похож на , или же .
Если же, мы перепишем цикл с помощью цикла , используя индексы, то работать такой подход будет только с последовательностями:
А с итерируемыми объектами, последовательностями не являющимися, не будет:
Если же вам нужен , то следует использовать встроенную функцию :
Цикл использует итераторы
Как мы могли убедиться, цикл не использует индексы. Вместо этого он использует так называемые итераторы.
Итераторы — это такие штуки, которые, очевидно, можно итерировать 🙂
Получить итератор мы можем из любого итерируемого объекта.
Для этого нужно передать итерируемый объект во встроенную функцию :
После того, как мы получили итератор, мы можем передать его встроенной функции .
При каждом новом вызове, функция отдаёт один элемент. Если же в итераторе элементов больше не осталось, то функция породит исключение .
По-сути, это единственное, что мы может сделать с итератором: передать его функции .
Как только итератор становится пустым и порождается исключение , он становится совершенно бесполезным.
Boolean Contexts#
In this section, you’ll see some practical examples of how to use the Python operator, and learn how to take advantage of its somewhat unusual behavior to write better Python code.
There are two main situations where you can say you’re working in a Boolean context in Python:
- statements: conditional execution
- loops: conditional repetition
With an statement, you can decide your programs’ path of execution depending on the truth value of some conditions.
On the other hand, loops allow you to repeat a piece of code as long as a given condition remains true.
These two structures are part of what you’d call control flow statements. They help you decide your programs’ execution path.
You can use the Python operator to build Boolean expressions suitable for use with both statement and loops, as you’ll see in the next two sections.
Моя часть
- Чтобы
люди не говнокодилиубрать смысловую двойственность, во многих «классических» местах, где можно было бы использовать и «=» и «:=» есть ограничения, поэтому оператор «:=» нужно часто заключать в скобки. Эти случаи придётся просмотреть в разделе, - Приоритет выражений присваивания чуть выше, чем у запятой. Благодаря этому, при присваивании не образуются кортежи. Также это даёт возможность использовать оператор := при передаче аргументов в функцию.
- Выражения присваивания, находящиеся в генераторах, используют ту область видимости, в которой находится генератор. Это позволяет сохранять значения для повторного использования. А вот в lambda функциях это не сработает, они создают свою «анонимную» область видимости.
- Теперь и в генераторах словарей строго определён порядок вычислений: сначала считается ключ, а потом соответствующее ему значение
- Нельзя изменить в генераторе через присваивание переменную, использующуюся в итераторе.
- Можно отстрелить левую ногу при попытке через генератор с присваиванием изменить/создать переменную класса.
- Можно отстрелить правую ногу, подставив выражение присваивания в итерационное выражение.
Python Switch Case Statement
Python does not have a simple switch case construct. Coming from a Java or C++ background, you may find this to be a bit odd.
In C++ or Java, we have something like this:
string week(int i){ switch(i){ case 0: return “Sunday” break; case 1: return “Monday” break; case 2: return “Tuesday” break; case 3: return “Wednesday” break; case 4: return “Thursday” break; case 5: return “Friday” break; case 6: return “Saturday” break; default: return “Invalid day of week” } }
But Python does not have this. So, to get around this, we use Python’s built-in dictionary construct to implement cases and decided what to do when a case is met. We can also specify what to do when none is met.Follow this link to know more about Python Dictionary
A switch case has been requested for Python, but never made it. You can refer to the following link to find out what happened:
Реализация цикла for с помощью функции и цикла while
Используя полученные знания, мы можем написать цикл , не пользуясь самим циклом . 🙂
Чтобы сделать это, нам нужно:
- Получить итератор из итерируемого объекта.
- Вызвать функцию .
- Выполнить ‘тело цикла’.
- Закончить цикл, когда будет получено исключение .
Стоит заметить, что здесь мы использовали конструкцию . Многие о ней не знают. Она позволяет выполнять код, если исключения не возникло, и код был выполнен успешно.
Теперь мы знакомы с протоколом итератора.
А, говоря простым языком — с тем, как работает итерация в Python.
Функции и этот протокол формализуют. Механизм везде один и тот же. Будь то пресловутый цикл или генераторное выражение. Даже распаковка и «звёздочка» используют протокол итератора:
В случае, если мы передаём в итератор, то получаем тот же самый итератор
Подытожим.
Итерируемый объект — это что-то, что можно итерировать.Итератор — это сущность порождаемая функцией , с помощью которой происходит итерирование итерируемого объекта.
Итератор не имеет индексов и может быть использован только один раз.
Non-Boolean Contexts#
You can take advantage of the special features of the Python operator out of Boolean contexts. The rule of thumb is still that the result of your Boolean expressions is the first true operand or the last in the line.
Notice that the logical operators ( included) are evaluated before the assignment operator (), so you can assign the result of a Boolean expression to a variable in the same way you do with a common expression:
>>>
Here, the operator works as expected, returning the first true operand or the last operand if both are evaluated to false.
You can take advantage of this somewhat special behavior of in Python to implement a Pythonic solution to some quite common programming problems. Let’s take a look at some real-world examples.
Discussion
Alternatives B, C and D are motivated by the desire to specify
multiple cases with the same treatment using a variable representing a
set (usually a tuple) rather than spelling them out. The motivation
for this is usually that if one has several switches over the same set
of cases it’s a shame to have to spell out all the alternatives each
time. An additional motivation is to be able to specify ranges to
be matched easily and efficiently, similar to Pascal’s «1..1000:»
notation. At the same time we want to prevent the kind of mistake
that is common in exception handling (and which will be addressed in
Python 3000 by changing the syntax of the except clause): writing
«case 1, 2:» where «case (1, 2):» was meant, or vice versa.
The case could be made that the need is insufficient for the added
complexity; C doesn’t have a way to express ranges either, and it’s
used a lot more than Pascal these days. Also, if a dispatch method
based on dict lookup is chosen as the semantics, large ranges could be
inefficient (consider range(1, sys.maxint)).
4.2. for Statements¶
The statement in Python differs a bit from what you may be used
to in C or Pascal. Rather than always iterating over an arithmetic progression
of numbers (like in Pascal), or giving the user the ability to define both the
iteration step and halting condition (as C), Python’s statement
iterates over the items of any sequence (a list or a string), in the order that
they appear in the sequence. For example (no pun intended):
>>> # Measure some strings: ... words = 'cat', 'window', 'defenestrate' >>> for w in words ... print(w, len(w)) ... cat 3 window 6 defenestrate 12
Code that modifies a collection while iterating over that same collection can
be tricky to get right. Instead, it is usually more straight-forward to loop
over a copy of the collection or to create a new collection:
4.6. Defining Functions¶
We can create a function that writes the Fibonacci series to an arbitrary
boundary:
>>> def fib(n): # write Fibonacci series up to n ... """Print a Fibonacci series up to n.""" ... a, b = , 1 ... while a < n ... print(a, end=' ') ... a, b = b, a+b ... print() ... >>> # Now call the function we just defined: ... fib(2000) 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
The keyword introduces a function definition. It must be
followed by the function name and the parenthesized list of formal parameters.
The statements that form the body of the function start at the next line, and
must be indented.
The first statement of the function body can optionally be a string literal;
this string literal is the function’s documentation string, or docstring.
(More about docstrings can be found in the section .)
There are tools which use docstrings to automatically produce online or printed
documentation, or to let the user interactively browse through code; it’s good
practice to include docstrings in code that you write, so make a habit of it.
The execution of a function introduces a new symbol table used for the local
variables of the function. More precisely, all variable assignments in a
function store the value in the local symbol table; whereas variable references
first look in the local symbol table, then in the local symbol tables of
enclosing functions, then in the global symbol table, and finally in the table
of built-in names. Thus, global variables and variables of enclosing functions
cannot be directly assigned a value within a function (unless, for global
variables, named in a statement, or, for variables of enclosing
functions, named in a statement), although they may be
referenced.
The actual parameters (arguments) to a function call are introduced in the local
symbol table of the called function when it is called; thus, arguments are
passed using call by value (where the value is always an object reference,
not the value of the object). When a function calls another function, a new
local symbol table is created for that call.
A function definition associates the function name with the function object in
the current symbol table. The interpreter recognizes the object pointed to by
that name as a user-defined function. Other names can also point to that same
function object and can also be used to access the function:
>>> fib <function fib at 10042ed0> >>> f = fib >>> f(100) 0 1 1 2 3 5 8 13 21 34 55 89
Coming from other languages, you might object that is not a function but
a procedure since it doesn’t return a value. In fact, even functions without a
statement do return a value, albeit a rather boring one. This
value is called (it’s a built-in name). Writing the value is
normally suppressed by the interpreter if it would be the only value written.
You can see it if you really want to using :
>>> fib() >>> print(fib()) None
It is simple to write a function that returns a list of the numbers of the
Fibonacci series, instead of printing it:
>>> def fib2(n): # return Fibonacci series up to n ... """Return a list containing the Fibonacci series up to n.""" ... result = [] ... a, b = , 1 ... while a < n ... result.append(a) # see below ... a, b = b, a+b ... return result ... >>> f100 = fib2(100) # call it >>> f100 # write the result
This example, as usual, demonstrates some new Python features:
Solutions for Python Switch Case Statement
One way out would be to implement an if-elif-else ladder. Rather, we can use a dictionary to map cases to their functionality. Here, we define a function week() to tell us which day a certain day of the week is. A switcher is a dictionary that performs this mapping.
>>> def week(i): switcher={ 0:'Sunday', 1:'Monday', 2:'Tuesday', 3:'Wednesday', 4:'Thursday', 5:'Friday', 6:'Saturday' } return switcher.get(i,"Invalid day of week")
Now, we make calls to week() with different values.
>>> week(2)
‘Tuesday’
>>> week(0)
‘Sunday’
>>> week(7)
‘Invalid day of week’
>>> week(4.5)
‘Invalid day of week’
a. Using Python Functions & Lambdas
We can also use functions and lambdas in the dictionary.
>>> def zero(): return 'zero' >>> def one(): return 'one' >>> def indirect(i): switcher={ 0:zero, 1:one, 2:lambda:'two' } func=switcher.get(i,lambda :'Invalid') return func() >>> indirect(4)
‘Invalid’
>>> indirect(2)
‘two’
>>> indirect(1)
‘one’
>>> indirect(0.5)
‘Invalid’
b. With Python Classes
Using this concept with classes lets us choose a method at runtime.
>>> class Switcher(object): def indirect(self,i): method_name='number_'+str(i) method=getattr(self,method_name,lambda :'Invalid') return method() def number_0(self): return 'zero' def number_1(self): return 'one' def number_2(self): return 'two' >>> s=Switcher() >>> s.indirect(2)
‘two’
>>> s.indirect(4)
‘Invalid’
>>> s.number_1()
‘one’
So, this was all about Python Switch Case Statement. Hope you like our tutorial.
Спецификация изменяется во время реализации
- Для обеспечения согласованности с другими подобными исключениями, а также чтобы не вводить новое название, которое не обязательно будет удобно для конечных пользователей, первоначально предложенный подкласс TargetScopeError для SyntaxError был убран и понижен до обычного SyntaxError.
- Из-за ограничений в анализе таблицы символов CPython, эталонная реализация выражения присваивания вызывает SyntaxError для всех случаев использования внутри итераторов. Раньше это исключение возникало только если имя создаваемой переменной совпадало с тем, которое уже используется в итерационном выражении. Это может быть пересмотрено при наличии достаточно убедительных примеров, но дополнительная сложность кажется нецелесообразной для чисто «гипотетических» вариантов использования.
A numeric example
I have another example that quite impressed me at the time.
Where all variables are positive integers, and a is at least as large
as the n’th root of x, this algorithm returns the floor of the n’th
root of x (and roughly doubling the number of accurate bits per
iteration):
while a > (d := x // a**(n-1)): a = ((n-1)*a + d) // n return a
It’s not obvious why that works, but is no more obvious in the «loop
and a half» form. It’s hard to prove correctness without building on
the right insight (the «arithmetic mean — geometric mean inequality»),
and knowing some non-trivial things about how nested floor functions
behave. That is, the challenges are in the math, not really in the
coding.
If you do know all that, then the assignment-expression form is easily
read as «while the current guess is too large, get a smaller guess»,
where the «too large?» test and the new guess share an expensive
sub-expression.
To my eyes, the original form is harder to understand:
while True: d = x // a**(n-1) if a <= d: break a = ((n-1)*a + d) // n return a
Relative precedence of :=
The := operator groups more tightly than a comma in all syntactic
positions where it is legal, but less tightly than all other operators,
including or, and, not, and conditional expressions
(A if C else B). As follows from section
«Exceptional cases» above, it is never allowed at the same level as
=. In case a different grouping is desired, parentheses should be
used.
The := operator may be used directly in a positional function call
argument; however it is invalid directly in a keyword argument.
Some examples to clarify what’s technically valid or invalid:
# INVALID x := 0 # Valid alternative (x := 0) # INVALID x = y := 0 # Valid alternative x = (y := 0) # Valid len(lines := f.readlines()) # Valid foo(x := 3, cat='vector') # INVALID foo(cat=category := 'vector') # Valid alternative foo(cat=(category := 'vector'))
Most of the «valid» examples above are not recommended, since human
readers of Python source code who are quickly glancing at some code
may miss the distinction. But simple cases are not objectionable:
# Valid if any(len(longline := line) >= 100 for line in lines): print("Extremely long line:", longline)
Why not just raw dict?
The biggest push back on this idea is that we already have this problem solved.
You write the following code.
switch = { 1: method_on_one, 2: method_on_two, 3: method_three } result = switch.get(value, default_method_to_run)()
This works but is very low on the functionality level. We have a better solution here
I believe. Let’s take this example and see how it looks in python-switch vs raw dicts:
# with python-switch: while True: action = get_action(action) with switch(action) as s: s.case(, create_account) s.case('l', log_into_account) s.case('r', register_cage) s.case('u', update_availability) s.case(, view_bookings) s.case('x', exit_app) s.case('', lambda: None) s.case(range(1,6), lambda: set_level(action)) s.default(unknown_command) print('Result is {}'.format(s.result))
Now compare that to the espoused pythonic way:
# with raw dicts while True: action = get_action(action) switch = { 'c': create_account, 'a': create_account, 'l': log_into_account, 'r': register_cage, 'u': update_availability, 'v': view_bookings, 'b': view_bookings, 'x': exit_app, 1: lambda: set_level(action), 2: lambda: set_level(action), 3: lambda: set_level(action), 4: lambda: set_level(action), 5: lambda: set_level(action), '': lambda: None, } result = switch.get(action, unknown_command)() print('Result is {}'.format(result))
Personally, I much prefer to read and write the one above. That’s why I wrote this module.
It seems to convey the intent of switch way more than the dict. But either are options.
Зачем нужны условные инструкции
Фундаментальная важность условий для любого из языков программирования заключается в их возможности описывать большую часть логики работы программы. Говоря простыми словами, конструкция в Python указывает интерпретатору, следует ли выполнять определенный участок кода или нет
Говоря простыми словами, конструкция в Python указывает интерпретатору, следует ли выполнять определенный участок кода или нет.
Как и все прочие составные инструкции языка, оператор выбора также поддерживает свойство вложенности. Это означает, что использование позволяет создавать внутри программного модуля так называемое логическое ветвление.
Source File Encoding
Code in the core Python distribution should always use UTF-8 (or ASCII
in Python 2).
Files using ASCII (in Python 2) or UTF-8 (in Python 3) should not have
an encoding declaration.
In the standard library, non-default encodings should be used only for
test purposes or when a comment or docstring needs to mention an author
name that contains non-ASCII characters; otherwise, using \x,
\u, \U, or \N escapes is the preferred way to include
non-ASCII data in string literals.
For Python 3.0 and beyond, the following policy is prescribed for the
standard library (see PEP 3131): All identifiers in the Python
standard library MUST use ASCII-only identifiers, and SHOULD use
English words wherever feasible (in many cases, abbreviations and
technical terms are used which aren’t English). In addition, string
literals and comments must also be in ASCII. The only exceptions are
(a) test cases testing the non-ASCII features, and
(b) names of authors. Authors whose names are not based on the
Latin alphabet (latin-1, ISO/IEC 8859-1 character set) MUST provide
a transliteration of their names in this character set.