- Глава 1. Python: с чем его едят
- Глава 2. Ингредиенты Python: числа, строки и переменные
- Узнать тип переменной
type
- Зарезервированные слова
- Числа
- Строки
- Многострочный текст
- Преобразование в строку
str
- Конкатенация
+
- Умножение строки
*
- Посимвольное обращение к строке
[]
- Обращение к подстроке
[ start : end : step]
- Длина строки
len
- Разбить строку
split
- Объединить строку
join
- Начинается с ?
startswith
- Заканчивается на ?
endwith
find
rfind
count
isallnum
- Регистр, выравнивание, замена строки
- Узнать тип переменной
- Глава 3: Наполнение Python: списки, кортежи, словари и множества
- Глава 4: Корочка Python: структуры кода
- Комментарии:
#
- Продолжение строки:
\
- Операторы:
if
,elif
,else
- Булево сравнение:
and
or
!
- Что есть ложь?
- Оператор:
while
- Оператор:
for
- Включения
- Функции
- Функции - объекты первого класса. Поэтому можно передавать как аргументы
- Замыкания
- Анонимные функции:
lambda()
- Генераторы
- Декораторы (обертки над функциями)
- Пространство имен
- Обработка ошибок:
try
иexcept
- Комментарии:
Глава 1. Python: с чем его едят
Created: Jan 24, 2021 11:27 AM
В книге пример с youtube, но ссылка похоже очень старая и уже давно не работает - https://gdata.youtube.com/feeds/api/standardfeeds/top_rated?alt=json
В место нее я использовал json placeholder - https://jsonplaceholder.typicode.com/users
Без библиотеки requests
import json # Импорт всей библиотеки json
from urllib.request import urlopen
url = "https://jsonplaceholder.typicode.com/users"
response = urlopen(url)
content = response.read()
text = content.decode('utf8')
data = json.loads(text)
for user in data:
print(user['username'], ' - ', user['email'], ' - ', user['phone'])
- exp
- Импорт всей библиотеки json
- Импорт только функции urlopen из либы urllib.request
- Присвоение переменной значения с url до api
- Делаем запрос на сервер
- Записываем ответ от сервера в переменную content
- Декодим ответ от сервера
- Преобразуем строку с json в структуру для работы в python
- Цикл по списку пользователей
- Вывод данных о юзере
-
пример json-а
[ { "username": "Bret", "email": "Sincere@april.biz", "phone": "1-770-736-8031 x56442" }, { "username": "Antonette", "email": "Shanna@melissa.tv", "phone": "010-692-6593 x09125" }, ]
С библиотекой
import requests
url = "https://jsonplaceholder.typicode.com/users"
response = requests.get(url)
data = response.json()
for user in data:
print(user['username'], ' - ', user['email'], ' - ', user['phone'])
- exp
- Импорт всей библиотеки requests
- Присвоение переменной значения url-а
- Выполнение запроса
- Пока не знаю
- Вывод информации о пользователе
ответ
$ python3 request_example.py
Bret - Sincere@april.biz - 1-770-736-8031 x56442
Antonette - Shanna@melissa.tv - 010-692-6593 x09125
Samantha - Nathan@yesenia.net - 1-463-123-4447
Karianne - Julianne.OConner@kory.org - 493-170-9623 x156
Kamren - Lucio_Hettinger@annie.ca - (254)954-1289
Leopoldo_Corkery - Karley_Dach@jasper.info - 1-477-935-8478 x6430
Elwyn.Skiles - Telly.Hoeger@billy.biz - 210.067.6132
Maxime_Nienow - Sherwood@rosamond.me - 586.493.6943 x140
Delphine - Chaim_McDermott@dana.io - (775)976-6794 x41206
Moriah.Stanton - Rey.Padberg@karina.biz - 024-648-3804
Глава 2. Ингредиенты Python: числа, строки и переменные
Created: Jan 24, 2021 11:27 AM
Присваивание переменной
>>> a = 2
>>> print(a)
2
>>> b = a
>>> print(b)
2
>>>
Узнать тип переменной type
>>> type(a)
<class 'int'>
>>> type(b)
<class 'int'>
>>> type(21)
<class 'int'>
>>> type(9.9)
<class 'float'>
>>> type('dsa')
<class 'str'>
>>>
Зарезервированные слова
Числа
Целые числа (int
)
Пример
>>> 58
58
>>> a = 58
>>> print(a)
58
>>> type(a)
<class 'int'>
>>>
Преобразование в целое число int
>>> int(True)
1
>>> int(89.2)
89
>>> int('89')
89
>>>
Преобразовать строку к Int можно только если в строке валидное число Иначе будет исключение
>>> int('89.2')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '89.2'
Дробные числа (float
)
Пример
>>> 89.2
89.2
>>> b = 25.3
>>> print(b)
25.3
>>> type(b)
<class 'float'>
>>>
Преобразование в дробное число float
>>> float(True)
1.0
>>> float(89)
89.0
>>> float('89')
89.0
>>> float('89.1')
89.1
Тоже самое и с дробным числом
>>> float('89.1a')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: could not convert string to float: '89.1a'
>>>
Операторы
Строки
Пример
>>> 'text'
'text'
>>> c = 'text'
>>> print(c)
text
>>> type(c)
<class 'str'>
>>> c = "text"
>>> type(c)
<class 'str'>
>>>
Многострочный текст
>>> '''hello
... world'''
'hello\nworld'
>>> a = '''hello
... world'''
>>> print(a)
hello
world
>>>
Преобразование в строку str
пример
>>> str(12)
'12'
>>> str(True)
'True'
>>> str(89.2)
'89.2'
>>>
Конкатенация +
>>> "hello" + " world"
'hello world'
>>>
Умножение строки *
>>> 'test ' * 3
'test test test '
>>>
Посимвольное обращение к строке []
>>> text = "Lorem ipsum dolor sit amet"
>>> text[0] -- первый символ
'L'
>>> text[-1] -- последний символ
't'
>>> text[0:3] -- 3 символа с начала
'Lor'
>>> text[:-1] -- Вырезать последний символ
'Lorem ipsum dolor sit ame'
>>>
При выходе за пределы строки, происходит ошибка
>>> text[100]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: string index out of range
>>>
Обращение к подстроке [ start : end : step]
- Оператор
[:]
возвращает всю строку - Оператор
[start:]
- от start до конца - Оператор
[:end]
- от начала строки до end - 1 - Оператор
[start:end]
- от start до end - Оператор
[start:end:step]
- от start до end с шагом step
Развернуть строку
>>> text[-1::-1]
'tema tis rolod muspi meroL'
>>>
Длина строки len
>>> len(text)
26
>>>
Разбить строку split
>>> text.split(' ')
['Lorem', 'ipsum', 'dolor', 'sit', 'amet']
>>>
Объединить строку join
>>> split_text = text.split(' ')
>>> ', '.join(split_text)
'Lorem, ipsum, dolor, sit, amet'
>>>
Начинается с ? startswith
>>> text.startswith('Lorem')
True
>>> text.startswith('Lor')
True
>>> text.startswith('Lor1')
False
>>>
Заканчивается на ? endwith
>>> text.endswith('amet')
True
>>> text.endswith('am')
False
>>>
find
rfind
count
isallnum
Регистр, выравнивание, замена строки
strip
capitalize
title
upper
lower
swapcase
center
ljust
rjust
replace
Глава 3: Наполнение Python: списки, кортежи, словари и множества
Created: Jan 24, 2021 11:27 AM
Списки
Создание списка - []
или метод list()
Примеры списков
>>> empty_list = []
>>> print(empty_list)
[]
>>> test_list = list()
>>> print(test_list)
[]
>>> week_days = ['пн', 'вт']
>>> print(week_days)
['пн', 'вт']
>>>
Элементы списка могут повторятся
>>> uniq_list = ['test1', 'test2', 'test1']
>>> print(uniq_list)
['test1', 'test2', 'test1']
Обращение к элементам списка
>>> uniq_list = ['test1', 'test2', 'test3']
>>> print(uniq_list[1])
test2
>>> print(uniq_list[-1]) # Последний эл. списка
test3
При обращении к эл. списка которого нет - исключение
>>> print(uniq_list[3])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
Обращение к диапазону эл. и их замена
>>> list
['test1', 'test2', 'test3']
>>> list[1:3]
['test2', 'test3']
>>> list[1:3] = ['test3', 1]
>>> list
['test1', 'test3', 1]
>>> list[1:3] = ['test3'] # Если не указать значение то эл. удалиться
>>> list
['test1', 'test3']
>>> list[1:3] = ['test3', 1, 2] # если указать больше - добавиться
>>> list
['test1', 'test3', 1, 2]
Инверсия списка
>>> list = [1,2,3,4,5]
>>> list[::-1]
[5, 4, 3, 2, 1]
Многоуровневые списки
>>> list1 = ['test1', 'test2', 'test3']
>>> list2 = ['test4', 'test5', 'test6']
>>> list3 = [list1, li
license( list( list1 list2
>>> list3 = [list1, list2]
>>> print(list3)
[['test1', 'test2', 'test3'], ['test4', 'test5', 'test6']]
>>> print(list3[1][2])
test6
Эл. списка можно менять, а эл. строки - нельзя!
>>> list = ['test1', 'test2', 'test3']
>>> list
['test1', 'test2', 'test3']
>>> list[0] = 'test4'
>>> list
['test4', 'test2', 'test3']
>>> str = 'test'
>>> str[0] = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
Добавление в список
в конец - append
>>> list = [1,2,3]
>>> list.append(4)
>>> list
[1, 2, 3, 4]
В начало списка = insert(0)
>>> list = [1,2,3]
>>> list.insert(0, 0)
>>> list
[0, 1, 2, 3]
Также в конец списка - insert(len(), object)
>>> list.insert(len(list), 4)
>>> list
[0, 1, 2, 3, 4]
Удаление из списка: del
и remove
del
>>> list = [1,2,3]
>>> list
[1, 2, 3]
>>> del list[0]
>>> list
[2, 3]
remove
>>> list1 = ['test1', 'test2', 'test3']
>>> list1.remove('test1')
>>> list1
['test2', 'test3']
Вернуть эл. из списка и удалить его: pop
Вернуть 1-й эл
>>> list1 = [1,2,3]
>>> list1.pop(0)
1
>>> list1
[2, 3]
Вернуть последний эл.
>>> list1 = [1,2,3]
>>> list1.pop()
3
>>> list1.pop(-1)
2
Вернуть n-й эл.
>>> list1 = [1,2,3]
>>> list1.pop(1)
2
>>> list1
Узнать позицию эл. в списке: index
>>> list1 = ['test1', 'test2', 'test3']
>>> list1.index('test2')
1
Если будет 2 одинаковых эл. то вернется 1-й индекс
>>> list1 = ['test1', 'test2', 'test3', 'test1', 'test2']
>>> list1.index('test2')
1
Если не будет найден эл. - исключение
>>> list1 = ['test1', 'test2', 'test3', 'test1', 'test2']
>>> list1.index('test')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: 'test' is not in list
Узнать есть ли эл. в списке: in
>>> list1 = ['test1', 'test2', 'test3']
>>> 'test1' in list1
True
>>> 'test5' in list1
False
Скопировать список: copy
, list
, [:]
copy
>>> list1 = ['test1', 'test2', 'test3
>>> list2 = list1.copy()
>>> list2
['test1', 'test2', 'test3']
list
>>> list1 = ['test1', 'test2', 'test3']
>>> list2 = list(list1)
>>> list2
['test1', 'test2', 'test3']
>>> list1.append('test4')
>>> list1
['test1', 'test2', 'test3', 'test4']
>>> list2
['test1', 'test2', 'test3']
[:]
>>> list1 = ['test1', 'test2', 'test3']
>>> list2 = list1[:]
>>> list1
['test1', 'test2', 'test3']
>>> list1.append('test4')
>>> list1
['test1', 'test2', 'test3', 'test4']
>>> list2
['test1', 'test2', 'test3']
Кортежи
Создание кортежа: ()
>>> empty_tuple = ()
>>> empty_tuple
()
>>>
еще
>>> tuple = ('test1', 'test2', 'test3')
>>> tuple
('test1', 'test2', 'test3')
>>> tuple2 = 'test1', 'test2', 'test3'
>>> tuple
('test1', 'test2', 'test3')
>>> tuple2
('test1', 'test2', 'test3')
Можно вывести в переменные
>>> tuple = ('test1', 'test2', 'test3')
>>> t1, t2, t3 = tuple
>>> t1
'test1'
>>> t2
'test2'
>>> t3
'test3'
(Как и списки)
>>> list = ['test1', 'test2', 'test3']
>>> t1, t2, t3 = list
>>> t1
'test1'
Поменять значение 2-х переменных
>>> test1 = 'test3'
>>> test3 = 'test1'
>>> test1, test3
('test3', 'test1')
>>> test1, test3 = test3, test1
>>> test1, test3
('test1', 'test3')
Как и списки, кортежи можно объединить через +=
>>> test_tuple1 = 'test1', 'test2'
>>> test_tuple2 = 'test3', 'test4'
>>> test_tuple1 += test_tuple2
>>> test_tuple1
('test1', 'test2', 'test3', 'test4')
>>>
Словари
Создание словаря: {}
>>> empty_dict = {}
>>> empty_dict
{}
>>> dict = {'test1': 1, 'test2': 2}
>>> dict
{'test2': 2, 'test1': 1}
Преобразование в словарь: dict()
>>> list1 = [['test1', 'test2']]
>>> dict(list1)
{'test1': 'test2'}
>>> list1 = [['test1', 'test2'], ['test3', 1]]
>>> dict(list1)
{'test3': 1, 'test1': 'test2'}
Добавление/изменения эл. в словаре: []
Добавить
>>> test_dict = {'test1': 1, 'test2': 2}
>>> test_dict
{'test1': 1, 'test2': 2}
>>> test_dict['test3'] = 3
>>> test_dict
{'test3': 3, 'test1': 1, 'test2': 2}
Обновить
>>> test_dict = {'test1': 1, 'test2': 2}
>>> test_dict['test1'] = 3
>>> test_dict
{'test1': 3, 'test2': 2}
Удалить эл. словаря: del
>>> test_dict1 = {'test1': 1, 'test2': 2}
>>> del test_dict['test1']
>>> test_dict
{'test2': 2}
Множества
Множество - список из уникальных значений
Создание множества: set()
>>> empty_set = set()
>>> empty_set
set()
>>> test_set = {1,2,3,4,4}
>>> test_set
{1, 2, 3, 4}
Преобразовать в множеств
Срока превращается в множество из уникальных значений
>>> set('hello')
{'l', 'e', 'o', 'h'}
Список - в уникальное множество
>>> set(['test1', 'test2', 'test3', 'test1'])
{'test3', 'test2', 'test1'}
Словарь - в уникальное множество из ключей словаря
>>> test_dict = {'test1': 1, 'test2': 2, 'test3': 3}
>>> set(test_dict)
{'test2', 'test3', 'test1'}
# В принципе тоже самое что и keys, только множество
>>> test_dict = {'test1': 1, 'test2': 2, 'test3': 3}
>>> list(test_dict.keys())
['test3', 'test2', 'test1']
Словарь значений - в уникальное множество из значений словаря
>>> test_dict = {'test1': 1, 'test2': 2, 'test3': 1}
>>> set(test_dict.values())
{1, 2}
Глава 4: Корочка Python: структуры кода
Created: Jan 24, 2021 11:27 AM
Комментарии: #
>>> # Коммент
... 2 + 1
3
>>>
Продолжение строки: \
>>> 2 + 1 + \
... 3
6
>>>
Операторы: if
, elif
, else
if
a = True
if a:
print("a is True")
else:
print("a is False")
$ python3 ./test.py
a is True
Много if
a = False
b = False
if a:
if b:
print("a and b is True")
else:
print("a is True and b is False")
else:
if b:
print("a is False and b is True")
else:
print("a and b is False")
$ python3 ./test.py
a and b is False
elif
color = "green"
if color == "red":
print("color is red")
elif color == "green":
print("color is green")
else:
print("color is other color")
Булево сравнение: and
or
!
- = - равенство
>>> x = 7
>>> x == 7
True
>>> x == 5
False
- != - неравенство
>>> x != 5
True
>>> x != 7
False
- < - меньше
>>> x < 5
False
>>> x < 10
True
>>> x < 7
False
- <= - меньше или равно
>>> x <= 10
True
>>> x <= 7
True
>>> x <= 5
False
-
- больше
>>> x > 5
True
>>> x > 7
False
>>> x > 10
False
-
= - больше или равно
>>> x >= 5
True
>>> x >= 7
True
>>> x > 10
False
- in - включение
>>> numbers = [1,2,3]
>>> 2 in numbers
True
>>> 7 in numbers
False
- and
>>> x > 5 and x < 10
True
>>> x > 10 and x < 10
False
- or
>>> x > 5 or x > 10
True
Что есть ложь?
- Булева переменная False
- Значение None
- Целое число 0
- Дробное число 0.0
- пустая строка (‘’)
- пустой список ([])
- пустой кортеж (())
- пустой словарь ({})
- пустое множество (set())
Все остальное - истина!
Оператор: while
count = 1
while count <= 5:
print(count)
count += 1
$ python3 ./test.py
1
2
3
4
5
break
while True:
str = input("Введите символ [q для выхода]: ")
if str == "q":
break
print(str.capitalize())
$ python3 ./test.py
Введите символ [q для выхода]: w
W
Введите символ [q для выхода]: ee
Ee
Введите символ [q для выхода]: привет
Привет
Введите символ [q для выхода]: привет как дела?
Привет как дела?
Введите символ [q для выхода]: q
continue
while True:
val = input("Введите число [q для выхода]: ")
if val == "q":
break
number = int(val)
if number % 2 == 0:
continue
print(number, " Квадрат числа ", number*number )
$ python3 ./test.py
Введите число [q для выхода]: 1
1 Квадрат числа 1
Введите число [q для выхода]: 2
Введите число [q для выхода]: 3
3 Квадрат числа 9
Введите число [q для выхода]: 4
Введите число [q для выхода]: 5
5 Квадрат числа 25
Введите число [q для выхода]: 6
Введите число [q для выхода]: 7
7 Квадрат числа 49
Введите число [q для выхода]:
else
numbers = [1, 3, 5, 2]
index = 0
while index < len(numbers):
number = numbers[index]
if number % 2 == 0:
print("Есть четное число!", number)
break
index += 1
else:
print("Не найдено четных чисел")
Если не был вызов break, то перейдет в else
Оператор: for
>>> test_list = ['test1', 'test2', 'test3']
>>> for item in test_list:
... print(item)
...
test1
test2
test3
>>>
если по строке - то цикл по символьно
>>> for letter in 'hello, world!':
... print(letter)
...
h
e
l
l
o
,
w
o
r
l
d
!
по словарю, по умолчанию вернет ключи
>>> test_dict = {'test1': 1, 'test2': 2, 'test3': 3}
>>> for key in test_dict:
... print(key)
...
test1
test3
test2
по значениям
>>> test_dict = {'test1': 1, 'test2': 2, 'test3': 3}
>>> for val in test_dict.values():
... print(val)
...
1
3
2
по ключам и значениям
>>> for key, val in test_dict.items():
... print("Key is '", key, "' Value is '", val, "'")
...
Key is ' test1 ' Value is ' 1 '
Key is ' test3 ' Value is ' 3 '
Key is ' test2 ' Value is ' 2 '
else
test_list = ['test1', 'test2', 'test3']
for item in test_list:
print(item)
if item == 'test2':
break
else:
print("test")
$ python3 ./test.py
test1
test2
Если не был вызван break, то будет else
Включения
>>> test_list = [n for n in range(1,6)]
>>> test_list
[1, 2, 3, 4, 5]
Список из не четных чисел, к которым делается +10
>>> [n + 10 for n in range(1,6) if n % 2 == 1]
[11, 13, 15]
Включение словаря
>>> word = 'hello, world!'
>>> {letter: word.count(letter) for letter in word}
{'r': 1, 'l': 3, 'w': 1, ' ': 1, 'h': 1, ',': 1, '!': 1, 'o': 2, 'e': 1, 'd': 1}
Без вызова count() дважды на одну букву - убрать дубли через set()
>>> {letter: word.count(letter) for letter in set(word)}
{'r': 1, 'l': 3, 'w': 1, 'd': 1, 'h': 1, ',': 1, '!': 1, 'o': 2, 'e': 1, ' ': 1}
Убрать пробел
>>> {letter: word.count(letter) for letter in set(word) if letter != ' '}
{'r': 1, 'l': 3, 'w': 1, 'd': 1, 'h': 1, ',': 1, '!': 1, 'o': 2, 'e': 1}
Функции
def do_nothing():
pass
do_nothing()
def test_print():
print('test_print in def test_print')
test_print()
$ python3 ./test.py
test_print in def test_print
Ответ
Если не указан return, то вернется None
>>> def test_return():
... 1 + 1
...
>>> print(test_return())
None
Передача аргументов и получение ответа
def check_color(color):
if color == "red":
return "color is red"
elif color == "green":
return "color is green"
else:
return "color is other color"
print(check_color("red"))
print(check_color("green"))
$ python3 ./test.py
color is red
color is green
None это undef?
def test():
pass
print(test())
$ python3 ./test.py
None
>>> def is_none(var):
... if var is None:
... print("It's None")
... elif var:
... print("It's True")
... else:
... print("It's False")
...
>>> is_none(None)
It's None
>>> is_none(True)
It's True
>>> is_none(False)
It's False
>>> is_none([])
It's False
>>> is_none(())
It's False
>>> is_none([])
It's False
>>> is_none(0)
It's False
>>> is_none(0.0)
It's False
>>> is_none('')
It's False
>>> is_none("")
It's False
Позиционные аргументы
>>> def test_position(t1, t2, t3):
... return {'test1': t1, 'test2': t2, 'test3': t3}
...
>>> test_position(1,2,3)
{'test1': 1, 'test3': 3, 'test2': 2}
>>> test_position('a','b','c')
{'test1': 'a', 'test3': 'c', 'test2': 'b'}
Порядок важен, и кол-во аргументов важно. Если не будет хотяб 1, то исключение -
>>> test_position('a','b')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: test_position() missing 1 required positional argument: 't3'
больше тоже плохо
>>> test_position(1,2,3,4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: test_position() takes 3 positional arguments but 4 were given
Аргументы key = value
Чтобы не сломалась последовательность, можно указать какая переменная чему равна
>>> def test_position(t1, t2, t3):
... return {'test1': t1, 'test2': t2, 'test3': t3}
...
>>> test_position(t2 = 1, t3 = 2, t1 = 3)
{'test1': 3, 'test3': 2, 'test2': 1}
Также нельзя ни больше, ни меньше. Если будет 2 раза - исключение
>>> test_position(t2 = 1, t3 = 2, t1 = 3, t2 = 2)
File "<stdin>", line 1
SyntaxError: keyword argument repeated
Значения по умолчанию
>>> def test_position(t1, t2, t3 = 't3'):
... return {'test1': t1, 'test2': t2, 'test3': t3}
...
>>> test_position(t2 = 1, t1 = 1)
{'test1': 1, 'test3': 't3', 'test2': 1}
Дефолтные значения не чистятся!
def test_result(item, result=[]):
result.append(item)
return result
print(test_result(1))
print(test_result(2))
Можно проверить на None перед запуском
def test_result(args, result=None):
if result is None:
result = []
result.append(args)
return result
print(test_result(1))
print(test_result(2))
print(test_result(3, [1,2]))
$ python3 ./test.py
[1]
[2]
[1, 2, 3]
Позиционные аргументы через *
Обычно пишется как *args
args - будет неизменяемый кортеж (tuple)
Если указать * перед аргументом, то при вызове получим кортеж из аргументов
def test_ask(*arg):
print("Args is ", arg)
test_ask()
test_ask(1)
test_ask(1,2,3)
$ python3 test.py
Args is ()
Args is (1,)
Args is (1, 2, 3)
удобно использовать как список “остальных” аргументов
def test_req(var1, var2, *args):
print("Var1 is required", var1)
print("Var2 is required", var2)
print("Other params = ", args)
test_req('test1', 'test2', 'other test3')
Порядок при этом важен!
Если будет
def test_req(*args, var1, var2):
то при обращении к функции - исключение
$ python3 test.py
Traceback (most recent call last):
File "test.py", line 9, in <module>
test_req('other test3', 'test1', 'test2')
TypeError: test_req() missing 2 required keyword-only arguments: 'var1' and 'var2'
Также нельзя установить по умолчанию
def test_req(var1, var2, *args = (1)):
print("Var1 is required", var1)
$ python3 test.py
File "test.py", line 4
def test_req(var1, var2, *args = (1)):
^
SyntaxError: invalid syntax
Аргументы через ** - словарь
Тоже самое что и кортеж всех остальных, только ключи почему-то должны быть не строкой?
def test_req(val1, **kwargs):
print("Val1 is required", val1)
print("Other key/value params = ", kwargs)
print()
test_req(1, test1=1, test2=1, other_test3=1, yet_yet_yet = 3)
$ python3 test.py
Val1 is required 1
Other key/value params = {'test1': 1, 'test2': 1, 'other_test3': 1, 'yet_yet_yet': 3}
Дока к функциям: help
>>> def return1(var):
... 'Вернуть 1-й аргумент'
... return(var)
...
>>> help(return1)
Help on function return1 in module __main__:
return1(var)
Вернуть 1-й аргумент
(END)
def print_if_true(var, check):
'''
Вывести первый аргумент если второй аргумент равен True
Аргументы:
1. *var* - переменная которую нужно вывести
2. *check* - переменная по которой проверяется
'''
if check:
print(var)
help(print_if_true)
Help on function print_if_true in module __main__:
print_if_true(var, check)
Вывести первый аргумент если второй аргумент равен True
Аргументы:
1. *var* - переменная которую нужно вывести
2. *check* - переменная по которой проверяется
(END)
Вывод похож на man страницу. Чтоб вывести как строку
>>> print(return1.__doc__)
Вернуть 1-й аргумент
>>>
print(print_if_true.__doc__)
$ python3 test.py
Вывести первый аргумент если второй аргумент равен True
Аргументы:
1. *var* - переменная которую нужно вывести
2. *check* - переменная по которой проверяется
Функции - объекты первого класса. Поэтому можно передавать как аргументы
>>> def test():
... pass
...
>>> type(test)
<class 'function'>
Можно передать функцию как аргумент другой функции
>>> def answer():
... print(42)
...
>>> def run_func(func):
... func()
...
>>> run_func(answer)
42
с аргументами
def sum_two(arg1, arg2):
print(arg1 + arg2)
def run_two(func, v1, v2):
func(v1, v2)
run_two(sum_two, 4, 5)
$ python3 test.py
9
Функция в функции
def test_func1():
def test_func2():
print("Hello in func2")
test_func2()
print("Hello in func1")
test_func1()
$ python3 test.py
Hello in func2
Hello in func1
Замыкания
Замыкание — это функция, которая динамически генерируется другой функцией, и они обе могут изменяться и запоминать значения переменных, которые были созданы вне функции.
>>> def say_func(saying):
... def print_say():
... print(saying)
... return print_say
...
>>> a = say_func('test1')
a - будет ссылкой на функцию внутри другой функции
>>> print(a)
<function say_func.<locals>.print_say at 0x7fc7afc59c80>
Если вызвать - то вызовиться print_say
>>> a()
test1
Если переменная глобальная, то каждый вызов будет работать с ней
test_list = []
def say_func():
def print_say():
test_list.append(1)
return print_say
a = say_func()
b = say_func()
a()
b()
print(test_list)
$ python3 ./test.py
[1, 1]
Но у каждого замыкания будет своя локальная переменная
def say_func():
test_list = []
def print_say(item):
test_list.append(item)
print(test_list)
return print_say
a = say_func()
b = say_func()
a(1)
b(2)
a('hello')
b('world')
Анонимные функции: lambda()
def edit_text(text, func):
for word in text:
func(word)
def edit_word(word):
print(word.capitalize() + '!')
text = ['привет', 'я', 'список', 'слов', 'которые', 'нужно', 'изменить']
edit_text(text, edit_word)
- edit_text - принимает текст и функцию
- Для каждого слова в списке вызывается функция
- edit_word - принимает слово
- выводит слово с большой буквы и с восклицательным знаком
- edit_text(text, edit_word) - передаем текст и функцию
$ python3 ./test.py
Привет!
Я!
Список!
Слов!
Которые!
Нужно!
Изменить!
тоже самое но через лямбду
def edit_text(text, func):
for word in text:
func(word)
text = ['привет', 'я', 'список', 'слов', 'которые', 'нужно', 'изменить']
edit_text(text, lambda word: print(word.capitalize() + '!'))
- От слова lambda до двоеточия (:) - список аргументов.
- От : до закрывающей скобки - тело функции
можно даже в переменную сохранить))
>>> a = lambda : 1
>>> a
<function <lambda> at 0x7fc7afc59d08>
>>> a()
1
Генераторы
Особый тип списков - генераторы
>>> sum(range(1, 10))
45
>>> def my_range(start = 0, end = 10, step = 1):
... number = start
... while number < end:
... yield number
... number += step
...
>>> print(my_range)
<function my_range at 0x7f88811ac9d8>
че такое интересно yield
?
>>> r = my_range(1,5)
>>> print(r)
<generator object my_range at 0x7f88811c4468>
Смысл генератора - один раз вызвать и он заканчивается)
def my_range(start = 0, end = 10, step = 1):
number = start
while number < end:
yield number
number += step
a = my_range(2, 10)
b = my_range(10, 20)
for x in b:
print("B is ", x)
for i in a:
print("A is ", i)
Декораторы (обертки над функциями)
def print_debug(func):
def new_func(*args, **kwargs):
print("Вызов функции:", func.__name__)
print("Дока функции:", func.__doc__)
print("Позиционные аргументы:", args)
print("Аргументы ключ/значение:", kwargs)
result = func(*args, **kwargs)
print("Результат:", result)
return result
return new_func
def sum_two(a, b):
'''
Функция сложения двух аргументов
Возвращает сумму двух переданных аргументов
'''
return a + b
x = 22
y = 2
print(sum_two(x, y))
debug_func = print_debug(sum_two) # мануальное присваивание декоратора
debug_func(x, y)
24
Вызов функции: sum_two
Дока функции:
Функция сложения двух аргументов
Возвращает сумму двух переданных аргументов
Позиционные аргументы: (22, 2)
Аргументы ключ/значение: {}
Результат: 24
- print_debug - возвращает функцию которая вызывается аж в последней строке
До этого момента это объект функции, но без вызова
debug_func = print_debug(sum_two)
print(debug_func)
<function print_debug.<<locals>.new_func at 0x7f50313b6730>
В первом случае, просто вызов функции напрямую.
Через декоратор - идет обертка а затем вызов.
Не любой декоратор должен вызывать функцию
Можно добавить @название_декоратора в место мануального присваивания
def print_debug(func):
print('AAAAAAAAa')
def new_func(*args, **kwargs):
print("Вызов функции:", func.__name__)
print("Дока функции:", func.__doc__)
print("Позиционные аргументы:", args)
print("Аргументы ключ/значение:", kwargs)
result = func(*args, **kwargs)
print("Результат:", result)
return result
print('BBBBB')
return new_func
@print_debug
def sum_two(a, b):
'''
Функция сложения двух аргументов
Возвращает сумму двух переданных аргументов
'''
return a + b
x = 22
y = 2
print(sum_two(x, y))
AAAAAAAAa
BBBBB
Вызов функции: sum_two
Дока функции:
Функция сложения двух аргументов
Возвращает сумму двух переданных аргументов
Позиционные аргументы: (22, 2)
Аргументы ключ/значение: {}
Результат: 24
24
Как видно, в начале вызов декоратора, потом вызов функции, потом возврат результата
Можно несколько декораторов
def print_debug(func):
print('AAAAAAAAa')
def new_func(*args, **kwargs):
print("Вызов функции:", func.__name__)
print("Дока функции:", func.__doc__)
print("Позиционные аргументы:", args)
print("Аргументы ключ/значение:", kwargs)
result = func(*args, **kwargs)
print("Результат:", result)
return result
print('BBBBB')
return new_func
def square(func):
def new_func(*args, **kwargs):
result = func(*args, **kwargs)
print("Вызов функции возведения в квадрат")
return result * result
return new_func
@square
@print_debug
def sum_two(a, b):
'''
Функция сложения двух аргументов
Возвращает сумму двух переданных аргументов
'''
return a + b
x = 3
y = 2
print(sum_two(x, y))
В таком случае декораторы будут вызываться в обратном порядке, начиная с названия функции
@print_debug
@square
def sum_two(a, b):
'''
Функция сложения двух аргументов
Возвращает сумму двух переданных аргументов
'''
return a + b
x = 3
y = 2
print(sum_two(x, y))
AAAAAAAAa
BBBBB
Вызов функции: new_func
Дока функции: None
Позиционные аргументы: (3, 2)
Аргументы ключ/значение: {}
Вызов функции возведения в квадрат
Результат: 25
25
Пространство имен
- Глобальные переменные
hello = 'hello'
def print_hello():
print(hello)
print_hello()
$ python3 ./test.py
hello
Можно обращаться, но нельзя изменять!
hello = 'hello'
def print_hello():
print("Глобольная переменная равна = ", hello)
hello = 'bye'
print("Локальная переменная равна = ", hello)
print(hello)
print_hello()
Traceback (most recent call last):
File "./test.py", line 11, in <module>
print_hello()
File "./test.py", line 6, in print_hello
print("Глобольная переменная равна = ", hello)
UnboundLocalError: local variable 'hello' referenced before assignment
Но при этом, можно назвать одинаково
hello = 'hello'
def print_hello():
hello = 'bye'
print("Локальная переменная равна = ", hello)
print(hello)
print_hello()
print(hello)
Локальная переменная равна = bye
bye
hello
gloabl
Для доступа к глобальной переменной, используется global. Тогда можно изменять глобальную в функции
hello = 'hello'
def print_hello():
global hello
hello = 'bye'
print("Локальная переменная равна = ", hello)
print(hello)
print_hello()
print(hello)
Локальная переменная равна = bye
bye
bye
hello = 'hello'
def print_hello():
hello = 'bye'
print("locals:", locals())
print_hello()
print("globals: ", globals())
locals: {'hello': 'bye'}
globals: {'__builtins__': <module 'builtins' (built-in)>, '__doc__': None, '__cached__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7fc265e0e9b0>, '__spec__': None, 'print_hello': <function print_hello at 0x7fc265d792f0>, 'hello': 'hello', '__name__': '__main__', '__file__': './test.py', '__package__': None}
- locals() - возвращает список локальных имен переменных
- globals() - возвращает список глобальных имен переменных
Обработка ошибок: try
и except
Пример исключения
test_list = [1,2,3]
test_list[4]
Traceback (most recent call last):
File "./test.py", line 5, in <module>
test_list[4]
IndexError: list index out of range
avis@avis[20:50:51]:~/learn/python/book-simple-python$
Обработка
test_list = [1,2,3]
index = 4
try:
test_list[index]
except:
print("Нужна позиция с 0 до", len(test_list) - 1, "но получено: ", index)
avis@avis[20:52:56]:~/learn/python/book-simple-python$ python3 ./test.py
Нужна позиция с 0 до 2 но получено: 4
Если не указать тип исключения, то будут ловиться все исключения.
Формат - except тип_исключения as имя
test_list = [1,2,3]
while True:
index = input("Позиция? [q для выхода]: ")
if index == 'q':
break
try:
index = int(index)
print(test_list[index])
except IndexError as err:
print("Плохой индекс: ", index)
except Exception as other:
print("Другая ошибка: ", other)
Позиция? [q для выхода]: 1
2
Позиция? [q для выхода]: 0
1
Позиция? [q для выхода]: 200
Плохой индекс: 200
Позиция? [q для выхода]: да?
Другая ошибка: invalid literal for int() with base 10: 'да?'
Позиция? [q для выхода]: ну лад
Другая ошибка: invalid literal for int() with base 10: 'ну лад'
Позиция? [q для выхода]: 3
Плохой индекс: 3
Позиция? [q для выхода]: й
Другая ошибка: invalid literal for int() with base 10: 'й'
Позиция? [q для выхода]: q
Собственные исключения
class UppercaseException(Exception):
pass
text = ['test', 'upper', 'case', 'AAAAAAAA']
for word in text:
if word.isupper():
raise UppercaseException(word)
Traceback (most recent call last):
File "./test.py", line 10, in <module>
raise UppercaseException(word)
__main__.UppercaseException: AAAAAAAA
Создаем класс и вызываем его если встречаем слово все буквы которого с болькой
Если pass - то выводится стандатное исключение
но можно изменить?
class UppercaseException(Exception):
print("Почему все с большой????")
pass
text = ['test', 'upper', 'case', 'AAAAAAAA']
for word in text:
if word.isupper():
raise UppercaseException(word)
Почему все с большой????
Traceback (most recent call last):
File "./test.py", line 11, in <module>
raise UppercaseException(word)
__main__.UppercaseException: AAAAAAAA