Skip to content

Instantly share code, notes, and snippets.

@xamgore
Created October 22, 2017 22:06
Show Gist options
  • Save xamgore/08076aa3e9acc10fdda72e1a73e9800d to your computer and use it in GitHub Desktop.
Save xamgore/08076aa3e9acc10fdda72e1a73e9800d to your computer and use it in GitHub Desktop.
Python. Семинар 1.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Введение в Python"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Начало работы с Python"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Установка Python\n",
"\n",
"#### Linux / MacOS\n",
"* Обычно есть предустановленный\n",
"* Разные версии в менеджерах пакетов\n",
"* Самая свежая версия - установщик с сайта\n",
"\n",
"#### Windows\n",
"* Установщик с сайта\n",
"\n",
"(можно держать несколько версий в системе)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true,
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Системная переменная путей\n",
"\n",
"PATH - набор путей, для вызова программ из которых достаточно указать только название (без полного пути).\n",
"\n",
"Пример: python вместо /usr/bin/python\n",
"\n",
"Как найти, откуда запускается программа:\n",
"* Linux / MacOS: which python\n",
"* Windows: where python"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Установка библиотек для Python\n",
"\n",
"Индекс пакетов PyPI (Python Package Index).\n",
"\n",
"Там есть все популярные библиотеки.\n",
"\n",
"Пакеты можно устанавливать с помощью утилиты pip.\n",
"\n",
"Python 2.7.9+ или Python 3.4+ - pip уже стоит.\n",
"\n",
"Возможные проблемы:\n",
"* Компиляция библиотек\n",
"* Неправильные пути PATH и PYTHONPATH (аналог для библиотек Python)\n",
"* Дополнительные библиотеки для эффективности"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Виртуальное окружение (1)\n",
"\n",
"* pip устанавливает пакеты как бы глобально. При наличии больших проектов, в которых используется что-то тяжелое и ломающее обратную совместимость между релизами такое поведение становится проблемой.\n",
"\n",
"* virtualenv - это инструмент, позволяющий создавать виртуальные окружения с пакетами. Разные «песочницы» имеют разный набор пакетов разных версий. Проблема конфликтующих версия решается созданием отдельных песочниц для каждого проекта.\n",
"\n",
"* Устанавливаем virtualenv через pip:\n",
"\n",
"```bash\n",
"$ pip install virtualenv\n",
"```\n",
"\n",
"* Создаем новое окружение для проекта:\n",
"\n",
"```bash\n",
"$ cd my_project_folder\n",
"$ virtualenv my_project\n",
"```\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Виртуальное окружение (2)\n",
"\n",
"* Переключаемся на созданное виртуальное окружение\n",
"\n",
"```bash\n",
"$ source my_project/bin/activate\n",
"```\n",
"\n",
"* Далее можем ставить пакеты, как обычно\n",
"\n",
"```bash\n",
"$ pip install requests\n",
"```\n",
"\n",
"* Сохранить список всех установленных пакетов (и их версий) из текущего окружения в файл.\n",
"\n",
"```bash\n",
"$ pip freeze > requirements.txt\n",
"```\n",
"\n",
"* Установить все зависимости, указанные в файле\n",
"\n",
"```bash\n",
"$ pip install -r requirements.txt\n",
"```\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Дистрибутивы\n",
"\n",
"Python + популярные пакеты\n",
"* Anaconda\n",
"* ActivePython\n",
"* Enthought Canopy\n",
"* Python(x,y)\n",
"* WinPython\n",
"\n",
"Возможны сложности при установке новых библиотек не через установщик дистрибутива."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Conda\n",
"\n",
"* Conda - пакетный менеджер, может выполнять роль pip и virtualenv.\n",
"\n",
"* Miniconda - Python, пакетный менеджер Conda + все его зависимости.\n",
"\n",
"* Andaconda - кроссплатформенный дистрибутив Python. Miniconda + более 720 популярных пакетов.\n",
"\n",
"* pip позволяет распространять только исходные коды пакетов, conda позволяет распространять в том числе скомпилированные бинарники. Помимо этого, conda умеет отслеживать не-Python зависимости сборки.\n",
"\n",
"* Елси вы когда-либо пытались заставить работать OpenCV с Python, то вы оцените эту строку:\n",
"\n",
"```bash\n",
"conda install -c https://conda.binstar.org/menpo opencv3\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## IPython"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Среды разработки\n",
"\n",
"* Vim, SublimeText, Atom + Python\n",
"* IPython [Notebook]\n",
"* PyCharm Community / Professional Edition\n",
"\n",
"Получить студенческую лицензию на IDE от JetBrains можно [здесь](https://www.jetbrains.com/student/)."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### IPython: введение\n",
"\n",
"* IPython - интерактивная оболочка для языка Python.\n",
"\n",
"* Она поддерживает:\n",
"\n",
" * интроспекцию и дополнение имён модулей, классов, методов, переменных\n",
" \n",
" * работу с историей\n",
" \n",
" * использование стандартных команд UNIX, например, ls, систему “магических” команд %%magic\n",
" \n",
"* Установить можно с помощью менеджера пакетов pip\n",
"```bash\n",
"$ pip install \"ipython[all]\"\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### IPython: интроспекция и дополнение\n",
"\n",
"```python\n",
"In [1]: from builtins import di<TAB>\n",
"dict dir divmod\n",
"```\n",
"```python\n",
"In [2]: d = {\"foo\": \"bar\"}\n",
"```\n",
"```python\n",
"In [3]: d.c<TAB>\n",
"d.clear d.copy\n",
"```\n",
"```python\n",
"In [4]: def f():\n",
" ...: \"I do nothing and return 42.\"\n",
" ...: return 42\n",
" ...:\n",
"```\n",
"```python\n",
"In [5]: f? # вывод ?? также содержит исходный код\n",
"Type: function\n",
"String form: <function f at 0x103d68ae8>\n",
"File: ...\n",
"Definition: f()\n",
"Docstring: I do nothing and return 42.\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### IPython: работа с историей\n",
"\n",
"```python\n",
"# номер ячейки\n",
"# |\n",
"# v\n",
"In [1]: [1, 2, 3]\n",
"Out[1]: [1, 2, 3]\n",
"```\n",
"```python\n",
"In [2]: _[1:] # ссылка на предыдущую ячейку\n",
"Out[2]: [2, 3]\n",
"```\n",
"```python\n",
"In [3]: __[1:] # ссылка на две ячейки назад\n",
"Out[3]: [2, 3]\n",
"```\n",
"```python\n",
"In [4]: Out[2] == Out[3] # ссылка на ячейку по номеру\n",
"Out[4]: True\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### IPython: стандартные команды UNIX\n",
"\n",
"```python\n",
"In [1]: pwd\n",
"Out[1]: './cscenter/python'\n",
"```\n",
"```python\n",
"In [2]: ls lecture*.tex\n",
"lecture-base.tex lecture01.tex\n",
"```\n",
"```python\n",
"In [3]: cd /tmp\n",
"/tmp\n",
"```\n",
"```python\n",
"In [4]: !date\n",
"Wed 2 Sep 2015 23:26:54 MSK\n",
"```\n",
"```python\n",
"In [5]: output = !date\n",
"```\n",
"```python\n",
"In [6]: output\n",
"Out[6]: ['Wed 2 Sep 2015 23:27:08 MSK']\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### IPython: \"магические\" команды (1)\n",
"\n",
"* \"Магические\" команды отвечают за магию.\n",
"\n",
"* Однострочные \"магические\" команды начинаются с символа %, многострочные - с %%.\n",
"\n",
"* Пример однострочной \"магической\" команды, которая позволяет отредактировать и вычислить содержимое ячейки с указанным номером:\n",
"\n",
"```python\n",
"In [1]: def f():\n",
" ...: pass\n",
" ...:\n",
"```\n",
"```python\n",
"In [2]: %edit 1\n",
"IPython will make a temporary file named: [...] done. Executing edited code...\n",
"Out[2]: 'def f():\\n return 42\\n'\n",
"```\n",
"```python\n",
"In [3]: f()\n",
"Out[3]: 42\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### IPython: \"магические\" команды (2)\n",
"\n",
"* По умолчанию IPython работает в режиме %automagic, то есть префикс % у однострочных команд можно не писать.\n",
"\n",
"* Команды UNIX, которыми мы уже пользовались - это \"магические\" команды IPython, вызванные без префикса %.\n",
"\n",
"* Пример многострочной “магической” команды, которая сохраняет содержимое ячейки в указанный файл:\n",
"\n",
"```python\n",
"In [1]: %%writefile /tmp/example.py\n",
" ...: def f():\n",
" ...: return 42\n",
" ...:\n",
"Writing /tmp/example.py\n",
"```\n",
"```python\n",
"In [2]: %load /tmp/example.py\n",
"```\n",
"```python\n",
"In [4]: f()\n",
"Out[4]: 42\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### IPython: \"магические\" команды (3)\n",
"\n",
"```python\n",
"In [1]: env EDITOR\n",
"Out[1]: 'nano'\n",
"```\n",
"```python\n",
"In [2]: env EDITOR=emacs\n",
"env: EDITOR=emacs\n",
"```\n",
"```python\n",
"In [3]: %cpaste\n",
"Pasting code; enter '--' alone on the line to stop\n",
": def f():\n",
": return \"I'm badly indented!\"\n",
":--\n",
"```\n",
"```python\n",
"In [4]: f()\n",
"Out[4]: \"I'm badly indented!\"\n",
"```\n",
"```python\n",
"In [5]: %timeit sum(range(1000))\n",
"10000 loops, best of 3: 25.1 μs per loop\n",
"```\n",
"```python\n",
"In [6]: %lsmagic # DIY\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### IPython: резюме\n",
"\n",
"* IPython — удобная и полезная альтернатива стандартной интерактивной оболочке Python.\n",
"\n",
"* Мы поговорили только про основы её использования.\n",
" Больше информации можно найти на сайте:\n",
" http://ipython.org."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## PEP 8"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### PEP 8: базовые рекомендации\n",
"\n",
"[PEP 8](https://www.python.org/dev/peps/pep-0008/) содержит стилистические рекомендации по оформлению кода на Python.\n",
"\n",
"Базовые рекомендации:\n",
"* 4 пробела для отступов\n",
"\n",
"* длина строки не более 79 символов для кода и не более 72 символов для документации и комментариев\n",
"\n",
"* lower_case_with_underscores для переменных и имен функций, UPPER_CASE_WITH_UNDERSCORES для констант\n",
"\n",
"* Используйте backslash для разбиения слишком длинных выражений\n",
"\n",
"```python\n",
"this_is_a_very_long(function_call, 'with many parameters') \\\n",
" .that_returns_an_object_with_an_attribute\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### PEP 8: выражения\n",
"\n",
"* Для списков или кортежей с большим количеством элементов используйте перенос сразу после запятой\n",
"\n",
"```python\n",
"items = [\n",
" 'this is the first', 'set of items', 'with more items',\n",
" 'to come in this line', 'like this'\n",
"]\n",
"```\n",
"\n",
"* Унарные операции без пробелов, бинарные с одним пробелом с обеих сторон\n",
"\n",
"```python\n",
"exp = -1.05\n",
"value = (item_value / item_count ) * offset / exp\n",
"value = my_dict['key']\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### PEP 8: операторы (1)\n",
"\n",
"* Не пишите тело оператора на одной строке с самим оператором\n",
"\n",
"```python\n",
"if bar: x += 1 # Плохо\n",
"while bar: do_something() # Плохо\n",
"\n",
"if bar: # Лучше\n",
" x += 1\n",
"while bar:\n",
" do_something() # Лучше\n",
"```\n",
"\n",
"* Не используйте Йода-сравнения в if и while\n",
"\n",
"```python\n",
"if 'md5' == method: # Плохо\n",
" pass\n",
" \n",
"if method == 'md5' # Лучше\n",
" pass\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### PEP 8: операторы (2)\n",
"\n",
"* Для сравнения на равенство\n",
" * объектов используйте операторы == и !=\n",
" \n",
" * синглтонов используйте is и is not (напр. foo is not None)\n",
" \n",
" * Никогда не сравнивайте что-либо с True или False\n",
" \n",
" * булевых значений используйте сам объект или оператор not, например\n",
" \n",
" ```python\n",
" if foo: while not bar:\n",
" # ... # ...\n",
" ```\n",
" \n",
" * Проверяйте отсутствие элемента в словаре с помощью оператора not in\n",
" \n",
" ```python\n",
" if not key in d: # Плохо\n",
" if key not in d: # Лучше\n",
" ```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### PEP 8: функции\n",
"\n",
"* Не используйте пробелы до или после скобок при объявлении и вызове функции\n",
"\n",
"```python\n",
"def foo (x, y): # Плохо\n",
" pass\n",
"\n",
"foo( 42, 24 ) # Плохо\n",
"```\n",
"\n",
"* Документируйте функции следующим образом\n",
"\n",
"```python\n",
"def something_useful(arg, **options):\n",
" \"\"\"One-line summary.\n",
"\n",
" Optional longer description of the function\n",
" behaviour.\n",
" \"\"\"\n",
"```\n",
"\n",
"* Разделяйте определения функций двумя пустыми строками."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### PEP 8: инструменты (1)\n",
"\n",
"* В репозитории пакетов Python доступен одноимённый инструмент, позволяющий проверить файл на соответствие PEP-8.\n",
"\n",
"```bash\n",
"$ pip install pep8\n",
"$ pep8 ./file.py\n",
"./file.py:1:7: E201 whitespace after '('\n",
"./file.py:1:12: E202 whitespace before ')'\n",
"```\n",
"\n",
"* На просторах Интернета вы можете найти сайты, осуществляющую проверку на соответствие PEP-8.\n",
" Один из таких сайтов - http://pep8online.com/"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### PEP 8: инструменты (2)\n",
"\n",
"* autopep8 показывает, как можно исправить код в указанном файле, чтобы он удовлетворял требованиям PEP-8.\n",
"\n",
"```bash\n",
"$ pip install autopep8\n",
"$ autopep8 -v ./file.py\n",
"---> Applying global fix for E265\n",
"---> Applying global fix for W602\n",
"---> 2 issue(s) to fix {'E201': {1}, 'E202': {1}}\n",
"---> 1 issue(s) to fix {'E202': {1}}\n",
"---> 0 issue(s) to fix {}\n",
"def f(x, y):\n",
" return x, y\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Повторение"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Слайсы\n",
"\n",
"```python\n",
">>> xs = [1, 2, 3, 4] >>> s = \"foobar\"\n",
"```\n",
"```python\n",
">>> xs[:2] >>> s[:2]\n",
"[1, 2] 'fo'\n",
"```\n",
"```python\n",
">>> xs[2:] >>> s[2:]\n",
"[3, 4] 'obar'\n",
"```\n",
"```python\n",
">>> xs[1:3] >>> s[1:3]\n",
"[2, 3] 'oo'\n",
"```\n",
"```python\n",
">>> xs[0:4:2] >>> s[0:4:2]\n",
"[1, 3] 'fo'\n",
"```\n",
"```python\n",
">>> xs[:] >>> s[:]\n",
"[1, 2, 3, 4] 'foobar'\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true,
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Объявление функций\n",
"\n",
"```python\n",
"In [1]: def foo():\n",
" ...: return 42\n",
" ...: \n",
"```\n",
"```python\n",
"In [2]: foo()\n",
"Out[2]: 42\n",
"```\n",
"```python\n",
"In [3]: def foo():\n",
" ...: 42\n",
" ...: \n",
"```\n",
"```python\n",
"In [4]: foo()\n",
"# None\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Docstrings\n",
"\n",
"```python\n",
"In [1]: def foo():\n",
" ...: \"\"\"I return 42.\"\"\"\n",
" ...: return 42\n",
" ...: \n",
"```\n",
"```python\n",
"In [2]: foo.__doc__\n",
"Out[2]: 'I return 42.'\n",
"```\n",
"```python\n",
"In [3]: foo?\n",
"Signature: foo()\n",
"Docstring: I return 42.\n",
"File: ...\n",
"Type: function\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Именованные аргументы\n",
"\n",
"```python\n",
"In [1]: def min(x, y):\n",
" ...: return x if x < y else y\n",
" ...: \n",
"```\n",
"```python\n",
"In [2]: min(-1, 1)\n",
"Out[2]: -1\n",
"```\n",
"```python\n",
"In [3]: min(x=-1, y=1)\n",
"Out[3]: -1\n",
"```\n",
"```python\n",
"In [4]: min(x=-1, z=1)\n",
"---------------------------------------------------------------------------\n",
"TypeError Traceback (most recent call last)\n",
"<...> in <module>()\n",
"----> 1 min(x=-1, z=1)\n",
"\n",
"TypeError: min() got an unexpected keyword argument 'z'\n",
"\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Упаковка и распаковка\n",
"\n",
"```python\n",
"In [1]: def min(first, *args):\n",
" ...: res = first\n",
" ...: for arg in args:\n",
" ...: if arg < res:\n",
" ...: res = arg\n",
" ...: return res\n",
" ...: \n",
"```\n",
"```python\n",
"In [2]: min(1, 2, 3)\n",
"Out[2]: 1\n",
"```\n",
"```python\n",
"In [3]: min(*[1, 2, 3])\n",
"Out[3]: 1\n",
"```\n",
"```python\n",
"In [4]: min(*{1, 2, 3})\n",
"Out[4]: 1\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Больше распаковки\n",
"\n",
"```python\n",
"In [1]: acc, seen = [], set()\n",
"```\n",
"\n",
"* Почему в Python нет функции swap? \n",
"\n",
"```python\n",
"In [1]: x, y = 1, 2\n",
"\n",
"In [2]: y, x = x, y\n",
"```\n",
"\n",
"* В качестве правого аргумента можно использовать любой объект-итератор.\n",
"\n",
"\n",
"```python\n",
"In [4]: x, y, z = [1, 2, 3]\n",
"\n",
"In [5]: x, y, z = {1, 2, 3}\n",
"\n",
"In [6]: x, y, z = \"123\"\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Расширенный синтаксис распаковки\n",
"\n",
"* В Python 3 завезли расширенный синтаксис распаковки:\n",
"\n",
"```python\n",
"In [1]: first, *rest, last = range(1, 5)\n",
"```\n",
"```python\n",
"In [2]: first, rest, last\n",
"Out[2]: (1, [2, 3], 4)\n",
"```\n",
"```python\n",
"In [3]: first, *rest, last = [42]\n",
"---------------------------------------------------------------------------\n",
"ValueError Traceback (most recent call last)\n",
"<ipython-input-14-d0ae67d894e5> in <module>()\n",
"----> 1 first, *rest, last = [42]\n",
"\n",
"ValueError: not enough values to unpack (expected at least 2, got 1)\n",
"```\n",
"```python\n",
"In [4]: first\n",
"Out[4]: 1\n",
"\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Ключевые аргументы\n",
"\n",
"```python\n",
"In [1]: def unique(items, seen=set()):\n",
" ...: acc = []\n",
" ...: for item in items:\n",
" ...: if item not in seen:\n",
" ...: seen.add(item)\n",
" ...: acc.append(item)\n",
" ...: return acc\n",
" ...: \n",
"```\n",
"```python\n",
"In [2]: xs = [1, 1, 2, 3]\n",
"```\n",
"```python\n",
"In [3]: unique(xs)\n",
"Out[3]: [1, 2, 3]\n",
"```\n",
"```python\n",
"In [4]: unique(xs)\n",
"Out[4]: []\n",
"```\n",
"```python\n",
"In [5]: unique.__defaults__\n",
"Out[5]: ({1, 2, 3},)\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Ключевые аргументы\n",
"\n",
"```python\n",
"In [1]: def unique(items, seen=None):\n",
" ...: seen = set(seen or []) \n",
" ...: acc = []\n",
" ...: for item in items:\n",
" ...: if item not in seen:\n",
" ...: seen.add(item)\n",
" ...: acc.append(item)\n",
" ...: return acc\n",
" ...: \n",
"```\n",
"```python\n",
"In [2]: xs = [1, 1, 2, 3]\n",
"```\n",
"```python\n",
"In [3]: unique(xs)\n",
"Out[3]: [1, 2, 3]\n",
"```\n",
"```python\n",
"In [4]: unique(xs)\n",
"Out[4]: [1, 2, 3]\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Области видимости\n",
"\n",
"```python\n",
">>> min # builtin\n",
"<built-in function min>\n",
">>> min = 42 # global\n",
">>> def f(*args):\n",
"... min = 2\n",
"... def g(): # enclosing\n",
"... min = 4 # local\n",
"... print(min)\n",
"... \n",
"```\n",
"\n",
"* Поиск ведется в четырех областях видимости - локальной, затем в объемлющей функции, затем в глобальной и, наконец, во встроенной."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Области видимости: интроспекция\n",
"\n",
"```python\n",
"In [1]: min = 42\n",
"```\n",
"```python\n",
"In [2]: globals()\n",
"Out[2]: \n",
"{..., 'min': 42}\n",
"```\n",
"```python\n",
"In [3]: def f():\n",
" ...: min = 2\n",
" ...: print(locals())\n",
" ...: \n",
"```\n",
"```python\n",
"In [4]: f()\n",
"{'min': 2}\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Области видимости: замыкания\n",
"\n",
"```python\n",
"In [1]: def f():\n",
" ...: print(i)\n",
" ...: \n",
"```\n",
"```python\n",
"In [2]: for i in range(3):\n",
" ...: f()\n",
" ...: \n",
"0\n",
"1\n",
"2\n",
"```\n",
"\n",
"* Функции в Python могут использовать переменные из внешних областей видимости.\n",
"\n",
"* Поиск переменной осуществляется во время выполнения функции, а не в момент объявления."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Области видимости: оператор global\n",
"\n",
"```python\n",
"In [1]: min = 42\n",
"```\n",
"```python\n",
"In [2]: def f():\n",
" ...: global min\n",
" ...: min += 1\n",
" ...: return min\n",
" ...: \n",
"```\n",
"```python\n",
"In [3]: f()\n",
"Out[3]: 43\n",
"```\n",
"```python\n",
"In [4]: f()\n",
"Out[4]: 44\n",
"\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Области видимости: оператор nonlocal\n",
"\n",
"```python\n",
"In [1]: def cell(value=None):\n",
" ...: def get():\n",
" ...: return value\n",
" ...: def set(update):\n",
" ...: nonlocal value\n",
" ...: value = update\n",
" ...: return get, set\n",
" ...: \n",
"\n",
"In [2]: get, set = cell()\n",
"```\n",
"```python\n",
"In [3]: set(42)\n",
"\n",
"In [4]: get()\n",
"Out[4]: 42\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Области видимости: резюме\n",
"\n",
"* В Python четыре области видимости: встроенная, глобальная, объемлющая и локальная.\n",
"\n",
"* Поиск имени осуществляется от локальной к встроенной.\n",
"\n",
"* При использовании операции присваивания имя считается локальным. Это поведение можно изменить с помощью операторов global и nonlocal."
]
}
],
"metadata": {
"anaconda-cloud": {},
"celltoolbar": "Slideshow",
"kernelspec": {
"display_name": "Python [default]",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment