Язык программирования

Лекция № 2

Владимир Владимирович Руцкий rutsky.vladimir@gmail.com

_images/cgsg.png _images/pml30.png
1

План занятия

2

Повторение

3

Модули

4

Стандартная библиотека (1/2)

5

Стандартная библиотека (2/2)

6

Модуль random

>>> import random
>>> random.random()  # Случайное float число в диапазоне [0, 1)  
0.5827532718821743
>>> random.randint(15, 30)  # Случайное int число в диапазоне [15, 30]  
29
>>> random.uniform(3.5, 10.0) # Случайное float число из диапазона [3.5, 10.0] 
7.332874018578613
>>> # Есть некоторые популярные распределения: равномерное, Бета, экспоненциальное,
... # Гамма, Гаусса, Нормальное, Парето
... random.gauss(mu=0, sigma=1)  
0.512533053672749
>>> a = ['Alice', 'Bob', 'Valery']
>>> random.choice(a)  # Вернёт произвольный элемент последовательности 
'Valery'
>>> random.shuffle(a)  # Случайным образом перемешает последовательность
>>> a 
['Alice', 'Valery', 'Bob']
>>>
7

Способы импортирования (1/2)

>>> # При импортировании модуля его можно "переименовать"
... import random as rnd
>>> rnd.random()  
0.5827532718821743
>>> # Можно импортировать только некоторые имена в локальную область видимости
... from random import choice
>>> choice(['a', 'b', 'c', 'd'])  
'b'
>>> # Можно импортировать имя из модуля, и переименовать его:
... from random import uniform as unf
>>> unf(-3, 3)  
-2.519376744749322
>>> # Можно импортировать несколько модулей в одной команде (не рекомендуется)
... import random, os, sys
>>> sys.platform
'linux'
>>> # Можно импортировать несколько имён из модуля:
... from random import gammavariate as G, choice, uniform as unf
>>> # При импортировании имён из модулей в текущей области видимости создаются
... # ссылки на объекты из импортируемых модулей, копирования не происходит:
... rnd is random
True
>>> rnd.choice is choice
True
>>>
8

Способы импортирования (2/2)

>>> # Можно импортировать все имена из модуля в текущую область видимости:
... from random import *
>>> choice(['a', 'b', 'c', 'd'])  
'b'
>>> random()  
0.5827532718821743
>>> dir()  
[..., 'betavariate', 'choice', 'expovariate', 'gammavariate', 'gauss', 'getrandbits', ...]
>>>
9

Скрытие имён в модулях (1/2)

from ... import * не импортирует имена, начинающиеся с подчеркивания — в Python принято называть "скрытые" функции и имена с подчеркивания

# rndcolors1.py
from random import choice

colors = ["red", "green", "blue"]

def random_color():
    return choice(colors)
>>> from rndcolors1 import *  
>>> dir()  
[..., 'choice', 'colors', 'random_color']
>>>
# rndcolors2.py
from random import choice

_colors = ["red", "green", "blue"]

def random_color():
    return random.choice(_colors)
>>> from rndcolors2 import *  
>>> dir()  
[..., 'choice', 'random_color']
10

Скрытие имён в модулях (2/2)

Если в модуле объявлена глобальная переменная __all__, то с помощью from ... import * из этого модуля будут импортироваться только имена, перечисленные в списке или кортеже __all__

# rndcolors3.py
from random import choice

__all__ = ["random_color"]

colors = ["red", "green", "blue"]

def random_color():
    return random.choice(colors)
>>> from rndcolors3 import *  
>>> dir()  
[..., 'random_color']
11

Модуль builtins

>>> # Встроенные функции находятся в специальном модуле `builtins'
... import builtins
>>> builtins.print('Test!')
Test!
>>> builtins.print is print
True
>>>
12

Пакеты

Модули можно объединять в пакеты:

sound/           Пакет верхнего уровня
    __init__.py      Инициализация пакета работы со звуком (sound)
    formats/         Подпакет для конвертирования форматов файлов
        __init__.py
        wavread.py       (чтение wav)
        wavwrite.py      (запись wav)
    effects/         Подпакет для звуковых эффектов
        __init__.py
        echo.py          (эхо)
        surround.py      (фон)
        reverse.py       (обращение)

Использование:

# Импортируем модуль sound/effects/echo.py
import sound.effects.echo
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

или:

from sound.effects import echo
echo.echofilter(input, output, delay=0.7, atten=4)
13

Файл __init__.py

14

Функция dir()

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
>>> # Функция dir() позволяет получить список членов (атрибутов) объекта
... a = 30
>>> dir(a)  
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', ...
>>> a.__add__(3)
33
>>> def f(a, b):
...     """Вычисляет сумму двух чисел"""
...     c = a + b
...     return c
... 
>>> dir(f)  
['__annotations__', '__call__', '__class__', '__closure__', '__code__', ...
>>> f.__name__
'f'
>>> f.__doc__
'Вычисляет сумму двух чисел'
>>> f.__code__.co_varnames  # интроспекция — доступ к внутренней информации об объектах
('a', 'b', 'c')
>>> # Вызванная без аргументов, dir() возвращает список доступных имён в локальной
... # области видимости.
... dir()  
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', 'a', 'f']
>>> __name__
'__main__'
>>>
15

Способы выполнения кода на Python (1/2)

Прямые способы:

16

Способы выполнения кода на Python (2/2)

Косвенные способы — при импортировании модулей:

>>> import random  # В результате этой команды модуль будет интерпретирован
>>>

module.py:

print("This module '__name__' variable is:", __name__)

При прямом способе выполнения команды, вводимые в интерактивном режиме, или из интерпретируемого модуля, или из аргументов к python.exe -c, выполняются в виртуальном модуле с именем __main__:

C:\>C:\Python33\python.exe module.py
This module '__name__' variable is: __main__
C:\>

При интерпретировании модуля в результате импортирования (косвенный способ выполнения) __name__ будет указывать на имя модуля:

>>> import module
This module '__name__' variable is: module
17

Отладочный код в библиотеках

18

Шаблон программы на Python (1/2)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Шаблон программы на Python
#
# Это комментарий. Любую программу стоит начинать с описания того,
# для чего она предназначена.

# Импортируем необходимые модули
import sys

def main():
    """Main program function"""

    # sys.argv содержит список аргументов командной строки.
    # sys.argv[0] хранит имя запущенного скрипта.

    if len(sys.argv) == 1:
        print("Ошибка! Слишком мало аргументов!")
        sys.exit(1)

    else:
        print("Программа", sys.argv[0], "была запущена с аргументами:")
        for arg in sys.argv[1:]:
            print(arg)

if __name__ == "__main__":
    # Если скрипт запущен как "python.exe template.py",
    # то это условие будет выполнено и будет вызвана main().
    # Впоследствии можно будет написать тесты, которые будут
    # импортировать этот модуль и вызывать функции из него.
    main()
19

Шаблон программы на Python (2/2)

C:\>C:\Python33\python.exe template.py
Ошибка! Слишком мало аргументов!
C:\>C:\Python33\python.exe template.py Питон 1 2 3
Программа template.py была запущена с аргументами:
Питон
1
2
3
20

Модуль pprint

21

Имена (переменные) в Python

22

Области видимости

23

Область видимости в модуле

>>> import pprint
>>> # Содержимое текущей (локальной) области видимости можно получить
... # с помощью locals() (только на чтение)
... pprint.pprint(locals())  
{'__builtins__': <module 'builtins' (built-in)>,
 '__doc__': None,
 '__loader__': <class '_frozen_importlib.BuiltinImporter'>,
 '__name__': '__main__',
 '__package__': None,
 'pprint': <module 'pprint' from '/usr/lib/python3.3/pprint.py'>}
>>> # Создаём метку в текущей области видимости:
... a = 10
>>> pprint.pprint(locals())  
{'__builtins__': <module 'builtins' (built-in)>,
 '__doc__': None,
 '__loader__': <class '_frozen_importlib.BuiltinImporter'>,
 '__name__': '__main__',
 '__package__': None,
 'a': 10,
 'pprint': <module 'pprint' from '/usr/lib/python3.3/pprint.py'>}
>>> def my_sum(a, b):
...     return a + b
...
>>> pprint.pprint(locals())  
{'__builtins__': <module 'builtins' (built-in)>,
 '__doc__': None,
 '__loader__': <class '_frozen_importlib.BuiltinImporter'>,
 '__name__': '__main__',
 '__package__': None,
 'a': 10,
 'my_sum': <function my_sum at 0x7f1ca3dd38c0>,
 'pprint': <module 'pprint' from '/usr/lib/python3.3/pprint.py'>}
>>>
24

Область видимости в функции

>>> import pprint
>>> def my_sum(a, b):
...     # В функции своя локальная область видимости
...     print("my_sum 1:\n", pprint.pformat(locals()), sep='')
...     sum = a + b
...     print("my_sum 2:\n", pprint.pformat(locals()), sep='')
...     return sum
...
>>> pprint.pprint(locals())  
{'__builtins__': <module 'builtins' (built-in)>,
 '__doc__': None,
 '__loader__': <class '_frozen_importlib.BuiltinImporter'>,
 '__name__': '__main__',
 '__package__': None,
 'my_sum': <function my_sum at 0x7f1ca3dd38c0>,
 'pprint': <module 'pprint' from '/usr/lib/python3.3/pprint.py'>}
>>> my_sum(10, 20)  
my_sum 1:
{'a': 10, 'b': 20}
my_sum 2:
{'a': 10, 'b': 20, 'sum': 30}
30
>>> # Изменение в локальной области my_sum не меняет содержимое области
... # видимости модуля
... pprint.pprint(locals())  
{'__builtins__': <module 'builtins' (built-in)>,
 '__doc__': None,
 '__loader__': <class '_frozen_importlib.BuiltinImporter'>,
 '__name__': '__main__',
 '__package__': None,
 'my_sum': <function my_sum at 0x7f1ca3dd38c0>,
 'pprint': <module 'pprint' from '/usr/lib/python3.3/pprint.py'>}
>>>
25

Поиск имён

26

Глобальная область видимости

>>> import pprint
>>> # Глобальную область видимости можно получить с помощью globals()
>>> pprint.pprint(globals())  
{'__builtins__': <module 'builtins' (built-in)>,
 '__doc__': None,
 '__loader__': <class '_frozen_importlib.BuiltinImporter'>,
 '__name__': '__main__',
 '__package__': None,
 'pprint': <module 'pprint' from '/usr/lib/python3.3/pprint.py'>}
>>> # В блоке кода модуля глобальная о.в. совпадает с локальной
>>> globals() is locals()
True
>>> 
27

Команда global

>>> import pprint
>>> V1 = "global V1"  # определим глобальные переменные в модуле
>>> V2 = "global V2"
>>> V3 = "global V3"
>>> def func():
...     print("V1 =", V1)  # V1 находится из глобальной о.в.
...     V2 = "func() V2"   # метка помещается в локальную о.в., перекрывая глоб. V2
...     print("V2 =", V2)
...     global V3          # указываем, что метка V3 — из глобальной о.в.
...     V3 = "changed in func()"
...     print("V3 =", V3)
...
>>> pprint.pprint(locals())  
{'V1': 'global V1',
 'V2': 'global V2',
 'V3': 'global V3',
 ...
 'func': <function func at 0x7f1198dc8680>,
>>> func()
V1 = global V1
V2 = func() V2
V3 = changed in func()
>>> pprint.pprint(locals())  
{'V1': 'global V1',
 'V2': 'global V2',
 'V3': 'changed in func()',
 ...
 'func': <function func at 0x7f1198dc8680>,
>>> 
28

Функция enumerate()

>>> a = ["A", "B", "C"]
>>> list(enumerate(a))
[(0, 'A'), (1, 'B'), (2, 'C')]
>>> list(enumerate(a, 10))
[(10, 'A'), (11, 'B'), (12, 'C')]
>>> # Удобно использовать для получения индекса при итерации по последовательности
... for idx, val in enumerate(a):
...     print("idx =", idx, "val =", val)
...
idx = 0 val = A
idx = 1 val = B
idx = 2 val = C
>>>
29

Функция zip() (1/2)

30

Функция zip() (2/2)

>>> a = ["A", "B", "C"]
>>> b = ["a", "b", "c"]
>>> list(zip(a, b))
[('A', 'a'), ('B', 'b'), ('C', 'c')]
>>> # длина результирующей последовательности равна длине минимальной входной посл.
... list(zip(range(10), a, b))
[(0, 'A', 'a'), (1, 'B', 'b'), (2, 'C', 'c')]
>>> # Удобно использовать для одновременной итерации по нескольким посл.:
... for x, y in zip(a, b):
...     print(x, y)
...
A a
B b
C c
>>> for idx, (x, y) in enumerate(zip(a, b)):
...     print(idx, "-", x, y)
...
0 - A a
1 - B b
2 - C c
>>> list(zip(a))
[('A',), ('B',), ('C',)]
>>> list(zip(*a))
[('A', 'B', 'C')]
>>> M = [[11, 12, 13], [21, 22, 23], [31, 32, 33]]
>>> list(zip(*M))
[(11, 21, 31), (12, 22, 32), (13, 23, 33)]
>>>
31

Функция map() (1/2)

32

Функция map() (2/2)

>>> a = ["A", "B", "C"]
>>> def prefix(s, prefix="prefix_"):
...     return prefix + s
...
>>> # Результат: последовательность [prefix(a[0]), prefix(a[1]), prefix(a[2]), ...]
... list(map(prefix, a))
['prefix_A', 'prefix_B', 'prefix_C']
>>> b = ["zero_", "one_", "two_"]
>>> # Результат: последовательность [prefix(a[0], b[0]), prefix(a[1], b[1]), ...]
... list(map(prefix, a, b))
['zero_A', 'one_B', 'two_C']
>>> list(map(len, b))
[5, 4, 4]
>>>
33

Функция filter()

34

Форматирование строк

Документация: http://docs.python.org/3/library/string.html#formatstrings

>>> "Hello, {0}".format("Peter")
'Hello, Peter'
>>> "Hello, {0} {1}. Or maybe {1} {0}?".format("John", "Smith")
'Hello, John Smith. Or maybe Smith John?'
>>> "Hello, {} {} {}".format(1, 2, 3)
'Hello, 1 2 3'
>>> "Object: {0} - size is {size}, weight is {w}".format("potato", size=10, w="0.1 kg")
'Object: potato - size is 10, weight is 0.1 kg'
>>> "int: {0:d};  hex: {0:x};  oct: {0:o};  bin: {0:b}".format(30)
'int: 30;  hex: 1e;  oct: 36;  bin: 11110'
>>> "{:10.3}".format(3.141592653589793)
'      3.14'
>>> 
35

Литералы в других системах счисления

>>> # В Python можно записывать целочисленные литералы в разных системах счисления
... 0xA36832   # шестнадцатеричная
10709042
>>> 0o655      # восьмеричная
429
>>> 0b00011110 # двоичная
30
>>> # Строковые представления в разных системах счисления:
... hex(10709042)
'0xa36832'
>>> oct(429)
'0o655'
>>> bin(30)
'0b11110'
>>>
36

Неименованные функции

37

List comprehension (1/2)

38

List comprehension (2/2)

>>> # квадраты чисел от 0 до 9
... [x**2 for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> # квадраты четных чисел от 0 до 9:
... [x**2 for x in range(10) if x % 2 == 0]
[0, 4, 16, 36, 64]
>>> # кортеж
... (x**2 for x in range(10))
(0, 1, 4, 9, 16, 25, 36, 49, 64, 81)
>>> # словарь
... { "K" + str(i): i**2 for i in range(6)}
{'K0': 0, 'K1': 1, 'K2': 4, 'K3': 9, 'K4': 16, 'K5': 25, 'K6': 36}
>>>
39

Практика

40