Содержание
- 1 Дополнительные файлы Django-приложения
- 2 Special-casing conditional statements
- 3 Упрощенное создание менеджеров контекста.
- 4 Python Operator Overloading
- 5 Операторы сравнения Python
- 6 Python Boolean operators
- 7 Циклы
- 8 Арифметические операторы
- 9 Python associativity rule
- 10 Использование
- 11 Python Арифметические операторы
- 12 Конструкция switch case
- 13 Примеры использования менеджеров контекста:
- 14 Python ternary operator
- 15 Изменяемые и неизменяемые типы данных
- 16 Какие компании используют Python
- 17 Standard Library
- 18 Python relational operators
Дополнительные файлы Django-приложения
Перед размещением кода на Heroku, нам понадобится сделать четыре изменения в нашем проекте Pages:
- обновить ;
- создать новый файл ;
- установить на нашем веб-сервере ;
- изменить строчку в файле .
Внутри уже существующего файла уточним используемую версию Python — в нашем случае 3.8. Для этого добавим в нижней части файла следующие две строчки.
Pipfile
Python
python_version = «3.8»
1 2 |
requires python_version=»3.8″ |
Далее запускаем для генерации подходящего .
Shell
(pages) $ pipenv lock
1 | (pages)$pipenv lock |
В действительности, в поисках информации о виртуальном окружении, Heroku заглядывает внутрь нашего Pipfile.lock. По этой причине здесь нам пришлось добавить настройку версии языка программирования.
Затем создаем , который является специфическим файлом конфигурации для Heroku.
Shell
(pages) $ touch Procfile
1 | (pages)$touchProcfile |
Откройте при помощи текстового редактора и добавьте следующее:
Python
web: gunicorn pages_project.wsgi —log-file —
1 | webgunicorn pages_project.wsgi—log-file- |
Это говорит о том, что нам надо использовать Gunicorn, что является сервером, подходящем для продакшена, в то время как собственный сервер Django работает только в локальном окружении. Устанавливаем gunicorn при помощи Pipenv.
Shell
(pages) $ pipenv install gunicorn==19.9.0
1 | (pages)$pipenv install gunicorn==19.9.0 |
Конфигурация для веб-сервера находится в файле wsgi.py, который Django автоматически создает для каждого нового проекта. Он находится в основной папке нашего проекта. Поскольку наш проект называется , сам файл находится в .
Последний шаг — небольшое изменение в файле . Прокрутите вниз до части и добавьте . Результат должен получиться следующим:
Python
# pages_project/settings.py
ALLOWED_HOSTS =
1 2 |
# pages_project/settings.py ALLOWED_HOSTS=’*’ |
Однако мы использовали знак звездочки , а это значит, что все домены являются приемлемыми. На сайте продакшн-уровня вместо этого вам пришлось бы составить ясный список допустимых доменов.
Для проверки изменений мы выполним команду , добавляем новые файлы и затем коммитим их:
Shell
(pages) $ git status
(pages) $ git add -A
(pages) $ git commit -m «New updates for Heroku deployment»
1 2 3 |
(pages)$git status (pages)$git add-A (pages)$git commit-m»New updates for Heroku deployment» |
Теперь мы можем разместить код на GitHub, создав онлайн копию наших изменений в коде.
Shell
(pages) $ git push -u origin master
1 | (pages)$git push-uorigin master |
Special-casing conditional statements
One of the most popular use-cases is if and while statements. Instead
of a more general solution, this proposal enhances the syntax of these two
statements to add a means of capturing the compared value:
if re.search(pat, text) as match: print("Found:", match.group(0))
This works beautifully if and ONLY if the desired condition is based on the
truthiness of the captured value. It is thus effective for specific
use-cases (regex matches, socket reads that return '' when done), and
completely useless in more complicated cases (e.g. where the condition is
f(x) < 0 and you want to capture the value of f(x)). It also has
no benefit to list comprehensions.
Упрощенное создание менеджеров контекста.
Поддержка упрощенного создания менеджеров контекста предоставляется модулем .
Многие контекстные менеджеры, например, файлы и контексты на основе генераторов будут одноразовыми объектами. После вызова менеджер контекста больше не будет находиться в работоспособном состоянии (например, файл был закрыт или базовый генератор завершил выполнение).
Необходимость создания нового объекта менеджера контекста для каждого оператора — это самый простой способ избежать проблем с многопоточным кодом и вложенными операторами, пытающимися использовать один и тот же контекстный менеджер. Не случайно, что все стандартные менеджеры контекста модуля , поддерживающие повторное использование, происходят из модуля и все они уже разработаны для решения проблем, создаваемых потоковым и вложенным использованием.
Это означает, что для сохранения менеджера контекста с определенными аргументами инициализации, которые будут использоваться в нескольких , как правило, необходимо будет сохранить его в вызываемом объекте с нулевым аргументом, который затем вызывается в выражении контекста каждого оператора, а не кэшировать непосредственно менеджер контекста. Если это ограничение не применяется, это должно быть ясно указано в документации соответствующего контекстного менеджера.
Python Operator Overloading
Python supports operator overloading. There are specific methods to overload an operator for an object.
Let’s see what happens when an operator is not supported for a class.
class Data: id = 0 def __init__(self, i): self.id = i d1 = Data(10) d2 = Data(20) d3 = d1 + d2 print(d3.id)
Output:
Traceback (most recent call last): File "/Users/pankaj/Documents/PycharmProjects/PythonTutorialPro/hello-world/operators_examples.py", line 9, in <module> d3 = d1 + d2 TypeError: unsupported operand type(s) for +: 'Data' and 'Data'
If we have to support + operator for Data class, we have to define __add__() method for it. Let’s see the updated code and the output.
class Data: id = 0 def __init__(self, i): self.id = i def __add__(self, other): return Data(self.id + other.id) d1 = Data(10) d2 = Data(20) d3 = d1 + d2 print(d3.id)
Output: 30
Below table provide the methods to override to overload an operator in Python.
Operator | Description | Method |
---|---|---|
+ | Addition | __add__(self, other) |
– | Subtraction | __sub__(self, other) |
* | Multiplication | __mul__(self, other) |
True Division | __truediv__(self, other) | |
// | Floor Division | __floordiv__(self, other) |
% | Remainder | __mod__(self, other) |
** | Power | __pow__(self, other) |
& | Bitwise AND | __and__(self, other) |
| | Bitwise OR | __or__(self, other) |
^ | Bitwise XOR | __xor__(self, other) |
> | Greater than | __gt__(self, other) |
>= | Greater than or equal to | __ge__(self, other) |
< | Less than | __lt__(self, other) |
<= | Less than or equal to | __le__(self, other) |
== | Equal to | __eq__(self, other) |
!= | Not equal to | __ne__(self, other) |
Операторы сравнения Python
Следующие допущения переменная а 10, Ь является переменной величиной 20:
операторы
описание
примеров
==
Равный — сравните объекты для равенства
(A == B) возвращает значение False.
! =
Это не равно — сравнить два объекта не равны
(A! = B) возвращает истину.
Это не равно — сравнить два объекта не равны
(A б) возвращает истину. Этот оператор подобен! =.
>
Больше — Возвращает ли х больше у
(A> B) возвращает значение False.
Обратите внимание, что эти переменные капитализации имя. (A
> =
Больше или равно — Возвращает ли х больше или равно у.
(A> = B) возвращает значение False.
Следующий пример иллюстрирует сравнение всех операций Python:
#!/usr/bin/python # -*- coding: UTF-8 -*- a = 21 b = 10 c = 0 if ( a == b ): print "1 - a 等于 b" else: print "1 - a 不等于 b" if ( a != b ): print "2 - a 不等于 b" else: print "2 - a 等于 b" if ( a <> b ): print "3 - a 不等于 b" else: print "3 - a 等于 b" if ( a < b ): print "4 - a 小于 b" else: print "4 - a 大于等于 b" if ( a > b ): print "5 - a 大于 b" else: print "5 - a 小于等于 b" # 修改变量 a 和 b 的值 a = 5; b = 20; if ( a <= b ): print "6 - a 小于等于 b" else: print "6 - a 大于 b" if ( b >= a ): print "7 - b 大于等于 b" else: print "7 - b 小于 b"
Примеры вышеуказанного вывода:
1 - a 不等于 b 2 - a 不等于 b 3 - a 不等于 b 4 - a 大于等于 b 5 - a 大于 b 6 - a 小于等于 b 7 - b 大于等于 b
Python Boolean operators
In Python, we have , and boolean
operators. With boolean operators we perform logical operations. These are most often
used with and keywords.
andop.py
#!/usr/bin/env python # andop.py print(True and True) print(True and False) print(False and True) print(False and False)
This example shows the logical and operator. The logical and operator evaluates
to only if both operands are .
$ ./andop.py True False False False
The logical or operator evaluates to if either of the operands is .
orop.py
#!/usr/bin/env python # orop.py print(True or True) print(True or False) print(False or True) print(False or False)
If one of the sides of the operator is , the outcome of the operation is .
$ ./orop.py True True True False
The negation operator makes
and .
negation.py
#!/usr/bin/env python # negation.py print(not False) print(not True) print(not ( 4 < 3 ))
The example shows the not operator in action.
$ ./negation.py True False True
And, or operators are short circuit evaluated. Short circuit evaluation means
that the second argument is only evaluated if the first argument does not suffice to
determine the value of the expression: when the first argument of and evaluates to false,
the overall value must be false; and when the first argument of or evaluates to true,
the overall value must be true.
The following example demonstrates the short curcuit evaluation.
short_circuit.py
#!/usr/bin/env python # short_circuit.py x = 10 y = 0 if (y != 0 and x/y < 100): print("a small value")
The first part of the expression evaluates to . The second part of the
expression is not evaluated. Otherwise, we would get a .
Циклы
Циклом называется многократное повторение каких-либо операций, которое зависит от заданных условий. Циклы значительно упрощают написание программ, и в цикле присутствует условие и тело цикла.
Итерация «iteration» – однократное повторение тела цикла. Итерируемый объект – повторяемый объект «iterable». Он отдает один результат за итерацию. «Iterator» итератор – это объект, который позволяет получить следующий элемент цикла.
В Python можно использовать два цикла while и for.
Цикл while записывается как:
while <условие>: <блок кода>
Блок кода выделяется табуляцией, которая обычно составляет 4 пробела. В цикле могут быть опции «else», «elif» принудительная остановка, пропуск остатка цикла «continue». Цикл может быть бесконечным.
Цикл «for» записывается как
for <переменная> in <список>: <блок кода>
В цикле «for» происходит поочередный перебор последовательности нужное количество раз. Все операторы «else», «break», «continue» аналогичны операторам в цикле «while». Для исполнения скрипта определенное количество раз используется функция «range».
Арифметические операторы
Арифметические операторы обычно работают с числами. Есть операторы для сложения, вычитания, умножения, деления, модуля и экспоненциальных операций. Некоторые из этих операторов работают и со строками. Все арифметические операторы — специальные символы.
- +: оператор сложения;
- -: оператор вычитания;
- *: оператор умножения;
- /: оператор деления;
- **: экспоненциальный оператор;
- //: оператор деления этажей.
Давайте посмотрим на пример арифметических операторов в Python.
x = 15 y = 7 sum = x + y print("addition =", sum) subtraction = x - y print("subtraction =", subtraction) multiplication = x * y print("multiplication =", multiplication) division = x / y print("division =", division) modulus = x % y print("modulus =", modulus) exponent = x ** 2 print("exponent =", exponent) floor_division = x // y print("division =", floor_division) # 2
Вывод:
Python поддерживает операторы сложения и умножения для строк.
print("addition of strings =", ("Python" + " " + "Operators")) print("multiplication of strings =", ("Python" * 2))
Вывод:
addition of strings = Python Operators multiplication of strings = PythonPython
Python associativity rule
Sometimes the precedence is not satisfactory to determine the outcome of
an expression. There is another rule called associativity. The associativity
of operators determines the order of evaluation of operators with the same
precedence level.
9 / 3 * 3
What is the outcome of this expression, 9 or 1? The multiplication, deletion,
and the modulo operator are left to right associated. So the expression is
evaluated this way: and the result is 9.
Arithmetic, boolean, relational and bitwise operators are all left
to right associated.
On the other hand, the assignment operator is right associated.
>>> a = b = c = d = 0 >>> a, b, c, d (0, 0, 0, 0)
If the association was left to right, the previous expression would not be possible.
The compound assignment operators are right to left associated.
>>> j = 0 >>> j *= 3 + 1 >>> j 0
You might expect the result to be 1. But the actual result is 0. Because of
the associativity. The expression on the right is evaluated first and then
the compound assignment operator is applied.
In this chapter, we have talked about operators in Python.
Contents
Previous
Next
Использование
Теперь, несмотря на то, что существует множество классов, в которых реализована возможность использования , нам интересно посмотреть, как она работает, чтобы мы могли написать ее сами!
Во-первых, оператор with сохраняет ссылку на объект в объекте контекста.
Объект контекста — это объект, который содержит дополнительную информацию о своем состоянии, такую как модуль или область видимости и т. д. Это полезно, поскольку мы можем сохранять или восстанавливать состояние этого объекта.
А теперь идем дальше. После создания объекта контекста он вызывает метод dunder для объекта.
Оператор __enter__ фактически выполняет работу по открытию ресурсов для объекта, таких как файл или сокет. Обычно при необходимости мы можем реализовать его для сохранения состояния объекта контекста.
Теперь помните ключевое слово ? Это фактически возвращает объект контекста. Поскольку нам нужен объект, возвращаемый функцией open(), мы используем ключевое слово для получения объекта контекста.
Использование необязательно, особенно если у вас есть ссылка на исходный объект контекста в другом месте.
После этого мы входим во вложенный блок операторов.
После того, как вложенный блок закончился, ИЛИ, если в нем есть исключение, программа всегда выполняет для объекта контекста.
Это первая функция безопасности, о которой мы говорили ранее. Итак, что бы ни случилось, мы всегда будем использовать для освобождения ресурсов и выхода из контекста.
Наконец, если возможно, может быть реализован так, чтобы восстановить состояние объекта контекста, чтобы он вернулся в то состояние, к которому он принадлежал.
Чтобы было понятнее, давайте рассмотрим пример создания нашего собственного диспетчера контекста для класса.
Python Арифметические операторы
Следующие допущения переменная а 10, Ь является переменной величиной 20:
операторы | описание | примеров |
---|---|---|
+ | Плюс — два объекта добавлены | а + выход 30 б |
— | Сохранить — получить отрицательное число вычитается из другого числа или | а — Ь Выход -10 |
* | Умножение — перемножить два числа или возвращает строку повторяется несколько раз | выход 200 * б |
Кроме того — х делится на у | б / 2 выход | |
% | Modulo — возвращает остаток деления | б% в 0 выход |
** | Мощность — возвращает х, возведенное в степени у | а ** б 10 20-й мощности, выход +100000000000000000000 |
// | Take делящихся — Возвращает целую часть частного | 9 // 2 выхода 4, выход 9,0 // 2,0 4,0 |
Следующий пример демонстрирует Python все арифметические операторы в действии:
#!/usr/bin/python # -*- coding: UTF-8 -*- a = 21 b = 10 c = 0 c = a + b print "1 - c 的值为:", c c = a - b print "2 - c 的值为:", c c = a * b print "3 - c 的值为:", c c = a / b print "4 - c 的值为:", c c = a % b print "5 - c 的值为:", c # 修改变量 a 、b 、c a = 2 b = 3 c = a**b print "6 - c 的值为:", c a = 10 b = 5 c = a//b print "7 - c 的值为:", c
Примеры вышеуказанного вывода:
1 - c 的值为: 31 2 - c 的值为: 11 3 - c 的值为: 210 4 - c 的值为: 2 5 - c 的值为: 1 6 - c 的值为: 8 7 - c 的值为: 2
Конструкция switch case
В Python отсутствует инструкция switch case
В языках, где такая инструкция есть, она позволяет заменить собой несколько условий и более наглядно выразить сравнение с несколькими вариантами.
Свято место пусто не бывает, поэтому в питоне такое множественное ветвление, в обычном случае, выглядит как последовательность проверок
Однако есть и более экзотический вариант реализации этой конструкции, задействующий в основе своей python-словари
Использование словарей позволяет, в качестве значений, хранить вызовы функций, тем самым, делая эту конструкцию весьма и весьма мощной и гибкой.
Примеры использования менеджеров контекста:
@contextmanager def locked(lock): lock.acquire() try yield finally lock.release()
Использование:
with locked(myLock): # Здесь код выполняется с удержанным myLock. # lock.release() гарантированно будет выполнен, когда блок # будет завершен (даже по необработанному исключению).
Шаблон для открытия файла, который обеспечивает закрытие файла при завершении блока:
@contextmanager def opened(filename, mode="r"): f = open(filename, mode) try yield f finally f.close()
Использование:
with opened("/etc/passwd") as f for line in f print line.rstrip()
Временно перенаправить стандартный вывод для однопоточных программ:
@contextmanager def stdout_redirected(new_stdout): save_stdout = sys.stdout sys.stdout = new_stdout try yield None finally sys.stdout = save_stdout
Использование:
with opened(filename, "w") as f with stdout_redirected(f): print "Hello world"
Вариант с функцией , который также возвращает условие ошибки:
@contextmanager def opened_w_error(filename, mode="r"): try f = open(filename, mode) except IOError, err yield None, err else try yield f, None finally f.close()
Использование:
with opened_w_error("/etc/passwd", "a") as (f, err): if err print "IOError:", err else f.write("guido::0:0::/:/bin/sh\n")
Python ternary operator
A ternary operator is a simple terse conditional assignment statement.
exp1 if condition else exp2
If condition is true, exp1 is evaluated and the result is returned. If
the condition is false, exp2 is evaluated and its result is returned.
ternary.py
#!/usr/bin/env python # ternary.py age = 31 adult = True if age >= 18 else False print("Adult: {0}".format(adult))
In many countries the adulthood is based on your age.
You are adult if you are older than a certain age.
This is a situation for a ternary operator.
adult = True if age >= 18 else False
First the condition is evaluated. If the age is greater
or equal to 18, is returned.
If not, the value following the keyword is returned.
The returned value is then assigned to the variable.
$ ./ternary.py Adult: True
A 31 years old person is adult.
Изменяемые и неизменяемые типы данных
Только почему операторы is и == одинаково сравнивают неименованные значения intи string (например, 5 и «example»). Но при этом не ведут себя так же с неименованными списками (например, )?
В Python есть две разновидности типа данных:
- Изменяемые — те, которые можно изменять
- Неизменяемые – остаются неизменными (имеют одинаковое расположение в памяти, что is и проверяет) после их создания.
Изменяемые типы данных: list, dictionary, set и определяемые пользователем классы. Неизменяемые типы данных: int, float, decimal, bool, string, tuple, и range.
Python обрабатывает неизменяемые типы данных иначе. То есть сохраняет их в памяти только один раз.
Применим Python-функцию id(), которая вызывает уникальный идентификатор для каждого объекта:
s = "example" print("Id of s: " + str(id(s))) print("Id of the String 'example': " + str(id("example")) + " (note that it's the same as the variable s)") print("s is 'example': " + str(s is "example")) print("Change s to something else, then back to 'example'.") s = "something else" s = "example" print("Id of s: " + str(id(s))) print("s is 'example': " + str(s is "example")) print() list1 = list2 = list1 print("Id of list1: " + str(id(list1))) print("Id of list2: " + str(id(list2))) print("Id of : " + str(id()) + " (note that it's not the same as list1!)") print("list1 == list2: " + str(list1 == list2)) print("list1 is list2: " + str(list1 is list2)) print("Change list1 to something else, then back to the original () value.") list1 = list1 = print("Id of list1: " + str(id(list1))) print("list1 == list2: " + str(list1 == list2)) print("list1 is list2: " + str(list1 is list2))
Выполнение кода выдаст следующий результат:
Id of s: 22531456 Id of the String 'example': 22531456 (note that it's the same as the variable s) s is 'example': True Change s to something else, then back to 'example'. Id of s: 22531456 s is 'example': True Id of list1: 22103504 Id of list2: 22103504 Id of : 22104664 (note that it's not the same as list1!) list1 == list2: True list1 is list2: True Change list1 to something else, then back to the original () value. Id of list1: 22591368 list1 == list2: True list1 is list2: False
В первой части примера переменная возвратит тот же объект , которым она была инициализирована в начале, даже если мы изменим ее значение.
Но не возвращает тот же объект, значение которого равно . При этом создается новый объект, даже если он имеет то же значение, что и первый .
При выполнении кода вы получите разные идентификаторы для объектов, но они будут одинаковыми.
Какие компании используют Python
В основном Python используется стартапами и компаниями, которые разрабатывают крупные проекты. Вот лишь часть огромного списка:
- Alphabet использует язык для скраппинга в поисковике Google и реализации сервиса YouTube;
- One Laptop Per Child — для разработки интерфейса и модели функционирования;
- BitTorrent — для реализации сетей peer-to-peer;
- Агентство национальной безопасности США — для шифрования и анализа разведданных;
- ESRI — как инструмент настройки геоинформационных программ;
- Maya — для создания мультипликации;
- Pixar, Industrial Light & Magic — для создания анимационных фильмов;
- Intel, Cisco, HP, Seagate, Qualcomm и IBM — для тестирования;
- JPMorgan Chase, UBS, Getco и Citadel — для прогнозирования финансового рынка;
- NASA, Los Alamos, Fermilab, JPL — для научных вычислений;
- iRobot — для разработки коммерческих роботизированных устройств;
- IronPort — для реализации почтового сервера.
Standard Library
Using the find-pep505.py script_ an analysis of the Python 3.7 standard
library discovered up to 678 code snippets that could be replaced with use of
one of the None-aware operators:
$ find /usr/lib/python3.7 -name '*.py' | xargs python3.7 find-pep505.py <snip> Total None-coalescing `if` blocks: 449 Total None-coalescing `or`: 120 Total None-coalescing ternaries: 27 Total Safe navigation `and`: 13 Total Safe navigation `if` blocks: 61 Total Safe navigation ternaries: 8
Some of these are shown below as examples before and after converting to use the
new operators.
From bisect.py:
def insort_right(a, x, lo=0, hi=None): # ... if hi is None: hi = len(a) # ...
After updating to use the ??= augmented assignment statement:
def insort_right(a, x, lo=0, hi=None): # ... hi ??= len(a) # ...
From calendar.py:
encoding = options.encoding if encoding is None: encoding = sys.getdefaultencoding() optdict = dict(encoding=encoding, css=options.css)
After updating to use the ?? operator:
optdict = dict(encoding=options.encoding ?? sys.getdefaultencoding(), css=options.css)
mangle_from_ = True if policy is None else policy.mangle_from_
After updating:
mangle_from_ = policy?.mangle_from_ ?? True
From asyncio/subprocess.py:
def pipe_data_received(self, fd, data): if fd == 1: reader = self.stdout elif fd == 2: reader = self.stderr else: reader = None if reader is not None: reader.feed_data(data)
After updating to use the ?. operator:
def pipe_data_received(self, fd, data): if fd == 1: reader = self.stdout elif fd == 2: reader = self.stderr else: reader = None reader?.feed_data(data)
From asyncio/tasks.py:
try: await waiter finally: if timeout_handle is not None: timeout_handle.cancel()
After updating to use the ?. operator:
try: await waiter finally: timeout_handle?.cancel()
From ctypes/_aix.py:
if libpaths is None: libpaths = [] else: libpaths = libpaths.split(":")
After updating:
libpaths = libpaths?.split(":") ?? []
From os.py:
if entry.is_dir(): dirs.append(name) if entries is not None: entries.append(entry) else: nondirs.append(name)
After updating to use the ?. operator:
if entry.is_dir(): dirs.append(name) entries?.append(entry) else: nondirs.append(name)
From importlib/abc.py:
def find_module(self, fullname, path): if not hasattr(self, 'find_spec'): return None found = self.find_spec(fullname, path) return found.loader if found is not None else None
After partially updating:
def find_module(self, fullname, path): if not hasattr(self, 'find_spec'): return None return self.find_spec(fullname, path)?.loader
After extensive updating (arguably excessive, though that’s for the style
guides to determine):
def find_module(self, fullname, path): return getattr(self, 'find_spec', None)?.__call__(fullname, path)?.loader
From dis.py:
def _get_const_info(const_index, const_list): argval = const_index if const_list is not None: argval = const_list return argval, repr(argval)
After updating to use the ?[] and ?? operators:
Python relational operators
Relational operators are used to compare values. These operators always
result in a boolean value.
Symbol | Meaning |
---|---|
strictly less than | |
less than or equal to | |
greater than | |
greater than or equal to | |
equal to | |
not equal to | |
object identity | |
negated object identity |
The above table shows Python relational operators.
>>> 3 < 4 True >>> 4 == 3 False >>> 4 >= 3 True
As we already mentioned, the relational operators
return boolean values: or .
Notice that the relational operators are not limited to numbers. We can use them
for other objects as well. Although they might not always be meaningful.
>>> "six" == "six" True >>> 'a' < 'b' True
We can compare string objects, too.
>>> 'a' < 'b'
What exactly happens here? Computers do not know characters or strings. For them,
everything is just a number. Characters are special numbers stored in specific
tables, like ASCII.
>>> 'a' > 6 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unorderable types: str() > int()
It is not possible to use relational operators on different data types.
This code leads to a .
compare.py
#!/usr/bin/env python # compare.py print('a' < 'b') print("a is:", ord('a')) print("b is:", ord('b'))
Internally, the a and b characters are numbers. So when we compare two characters,
we compare their stored numbers. The built-in function
returns the ASCII value of a single character.
$ ./compare.py True a is: 97 b is: 98
In fact, we compare two numbers: 97 and 98.
>>> "ab" > "aa" True
Say we have a string with more characters. If the first characters are equal, we
compare the next ones. In our case, the b character at the second position has a
greater value than the a character. That is why «ab» string is greater than «aa» string.
Comparing strings in such a way does not make much sense, of course. But it is
technically possible.