Python Основы
Введение
Python, произностися как Пайтон, в русском языке распространено название Питон
— высокоуровневый язык программирования общего назначения, ориентированный на
повышение производительности разработчика и читаемости кода.
Синтаксис ядра Python минималистичен. В то же время стандартная библиотека
включает большой объём полезных функций.
Python поддерживает структурное, объектно-ориентированное, функциональное,
императивное и аспектно-ориентированное программирование.
Основные архитектурные черты — динамическая типизация, автоматическое управление
памятью, полная интроспекция, механизм обработки исключений, поддержка многопоточных
вычислений, высокоуровневые структуры данных.
Поддерживается разбиение программ на модули, которые, в свою очередь, могут объединяться в пакеты.
Эталонной реализацией Python является интерпретатор CPython, поддерживающий
большинство активно используемых платформ.
Он распространяется под свободной лицензией Python Software Foundation License,
позволяющей использовать его без ограничений в любых приложениях, включая проприетарные.
Есть реализация интерпретатора для JVM с возможностью компиляции, CLR, LLVM,
другие независимые реализации. Проект PyPy использует JIT-компиляцию, которая
значительно увеличивает скорость выполнения Python-программ.
Python — активно развивающийся язык программирования, новые версии с
добавлением/изменением языковых свойств выходят примерно раз в два
с половиной года.
Язык не подвергался официальной стандартизации, роль
стандарта де-факто выполняет CPython, разрабатываемый под контролем автора языка.
В настоящий момент (апрель 2021)
Python занимает третье место в рейтинге TIOBE с показателем 11,03%.
Аналитики отмечают, что это самый высокий балл Python за все время его присутствия в
рейтинге.
Посмотреть текущий рейтинг можно
здесь
Этот подраздел раздела о Python я назвал основами не потому, что здесь идёт речь только самых простых концепциях. Здесь также разбираются некоторые
особенности языка, без которых иногда очень сложно вообще понять что написано в чужом коде.
В Python одну и ту же задачу можно сделать совершенно разными
способами с этим можно жить и работать. Но даже если способ концептуально один, оформление кода может очень существенно различаться.
Начинающему изучать Python многое может показаться
избыточным или чересчур запутанным, но многие концепции решают довольно серьёзные задачи и о них желательно знать.
Python рекламируют как простой для понимания язык. print("Hello World!") - это хороший пример лакончиного кода, особенно на фоне
Java
,
C#
и подобных языков.
Однако, при погружении в более-менее профессиональную разработку, начинающий пользователь Python сталкивается с необязательными, но общепринятыми в
сообществе или конкретной команде практики, которые существенно увеличивают число строк. Простейший пример -
составные аннотации типов
,
более сложный пример - применение
pydantic
.
Писать короткий код, который решает проблему на Python можно. Это большой плюс языка. В реальности код будет не очень коротким, значительная часть кода
не будет непосредственно относиться к решаемой проблеме. Минус это или нет я не знаю. Думаю, что полезно знать об этом заранее, чтобы потом не разочароваться.
В разделе «Основы Python» размещены как статьи о том как начать работу с языком так и статьи которые сильно упростят жизнь в будущем даже если для
написание первых скриптов они и не нужны.
РЕКЛАМА от Яндекса. Может быть недоступна в вашем регионе
Конец рекламы. Если там пусто считайте это рекламой моей телеги
Hello World!
Инструкция по запуску первой программы в Python
Убедитесь, что Python установлен и команда
python -V
Показывает версию Python, например
Python 3.12.1
Теперь вы можете сходу выполнить небольшой Python скрипт с помощью опции -c
python -c "print('Hiya!')"
Hiya!
Опция -с может пригодиться для совсем коротких скриптов. Более сложные действия можно выполнять в интерактивном режиме а самый типичный способ запуска скриптов - из отдельных файлов с расширением .py
Перейдём к созданияю файла со скриптом.
Если вы работаете в Linux, UNIX или Bash в Windows перейдите в свою домашнюю директорию
В Linux , Unix и PowerShell
cd ~
В Windows cmd
cd /mnt/c/Users/username
Создайте директорию python
Bash
mkdir python
New-Item -Path ".\" -Name "python" -ItemType "directory"
Перейдите в неё, создайте файл hello_world.py
и откройте его любым тестовым редактором
Bash
cd python
touch hello_world.py
vi hello_world.py
cd python
New-Item -Path . -Name "hello_world.py" -ItemType "file"
notepad hello_world.py
Вставьте туда следующий код
print("Hello World!")
Выполните
python hello_world.py
В терминале должно появиться сообщение
Hello World!
Больше деталей о запуске скриптов вы можете найти в следующем параграфе - «Запуск Python скрипта» и затем в if __name__ == "__main__":
Запуск скрипта
Чтобы запустить .py скрипт введите
python имя_файла.py
Результат такого запуска зависит от того, что указано после if __name__ == "__main__": если это условие вообще есть
print("Hello!")
python sample.py
Hello!
Теперь то же самое но в функции
def say_hello(): print("Hello!")
python sample.py
Ничего не произошло потому что функцию никто не вызвал
Можно добавить вызов функции следующим образом
def say_hello(): print("Hello!") say_hello()
python sample.py
Hello!
В этом случае функция будет вызываться всегда - как при запуске скрипта из терминала так и при импорте в другой модуль настроить это поведение можно с помощью переменной __name__ а точнее - с помощью условия if __name__ == "__main__":
Отступы (indentation)
Python не является языком поддерживающим свободный формат. Блоки кода не
разделяются с помощью { }
Вместо этого блоки разделяются отступами по так называемому правилу оффсайда (Off-side rule)
Демонстрация
Рассмотрим файл for_loop.py
for i in range(1, 4): print(i)
python for_loop.py
1
2
3
Всё работает прекрасно. Обратите внимание, что выведены были только i от 1 до 3. 4 python не вывел.
Если написать код не в одну строку, а следующим образом
for i in range(1, 4):
print(i)
то работать код не будет. Получится ошибка
File "/home/andrei/python/for_loop.py", line 2 print(i) ^ IndentationError: expected an indented block
Поэтому нужно поставить перед print пробел
for i in range(1, 4):
print(i)
python for_loop.py
1
2
3
Вместо одного пробела можно поставить табуляцию, но лучше поставить два или четыре пробела подряд.
PEP8 - документ, в котором собраны рекомендации по написанию Python кода говорит:
Use 4 spaces per indentation level
Нельзя смешивать в одном файле отступы в виде табуляций и в виде
пробелов.
Если вы пишете код в
PyCharm
или подобном
IDE
то он автоматически исправит эту ошибку, но обычный текстовый редактор этого не сделает.
Выберите один стиль и придерживайтесь его.
Про то как правильно переносить слишком длинные строки можете прочитать здесь
Печать спецсимволов HTML
Скрипт, с помощью которого можно распечатать определённое число спецсимволов HTML
for i in range(100001, 125000):
print("<tr><td>&#", i, ";</td><td>&#", i, ";</td></tr>")
Ссылки
Psyco
Shedskin
PyPy
Cython
Jython
IronPython
IDLE
Синтаксис
Set в фигурных скобках. Элемент добавляется с помощью .add()
if __name__ == '__main__'
__name__ это атрибут. Прочитать про предопределённые атрибуты можно
здесь
другим примером атрибута файла является
__file__
Чтобы разобраться в смысле этой строки создадим два файла.
first_module.py
и
second_module.py
В первом напишем
print(f"Имя первого модуля: {__name__}")
# Если не любите f-string напишите:
print("Имя первого модуля: {}".format(__name__))
Запустим его
python3 first_module.py
Имя первого модуля: __main__
Во втором запишем
import first_module
Запустим его
python3 second_module.py
Имя первого модуля: __first_module__
Вывод: когда модуль запущен непосредственно, его __name__ это __main__
Когда модуль импортирован в другой модуль, его __name__ это __название_py_файла__
Теперь когда все ясно, можно добавить в наш код условие if __name__ == "__main__"
def say_hello(): print("Hello!") def display_name(): print(f"Имя первого модуля: {__name__}") if __name__ == "__main__": say_hello()
Hello!
Или
def say_hello(): print("Hello!") def display_name(): print(f"Имя первого модуля: {__name__}") if __name__ == "__main__": display_name()
Имя первого модуля: __main__
Суть в том, что теперь мы определяем что будет выполняться при вызове этого скрипта а что нет.
Где это может пригодиться:
Есть два скрипта которые вызываются из главного файла main.py: db.py и update.py
db.py создает базу данных и пишет туда. update.py выводит какие-то данные в терминал и добавляет что-то в ту же базу.
Когда скрипты запускались из main.py то всё работало, но вдруг при очередном обновлении появились ошибки в update.py и хочется
запустить его отдельно чтобы посмотреть его вывод в терминал.
Скрипт не запустится, потому что нет базы данных - её не создал db.py так как его не запускали.
Если добавить условие, что при вызове update.py как __main__ не нужно обновлять базу, то тогда можно посмотреть только вывод в терминал, а при запуске
из main.py ничего не изменится.
__file__
Из официальной документации мы знаем, что __file__ это
The pathname of the file from which the module was loaded, if it was loaded from a file.
The __file__ attribute may be missing for certain types of modules, such as C modules that are statically linked into the interpreter.
For extension modules loaded dynamically from a shared library, it’s the pathname of the shared library file.
Типичное применение - вместе с os.path.dirname()
file_path = os.path.join(os.path.dirname(__file__), filename)
Пакеты Python в Linux
Узнать сколько всего python3 пакетов в репозитории Ubuntu
apt-cache search python3 | wc -l
3472
Изучить их названия можно с помощью less
apt-cache search python3 | less
alembic - lightweight database migration tool for SQLAlchemy
brltty - Access software for a blind person using a braille display
debian-goodies - Small toolbox-style utilities for Debian systems
devscripts - scripts to make the life of a Debian Package maintainer easier
libcrack2-dev - pro-active password checker library - development files
…
Проверить, существует ли файл hosts
#!/usr/bin/python3
import os.path
if os.path.exists("/etc/hosts"):
print("hosts file exists")
else:
print("no hosts file")
или
#!/usr/bin/python3
try:
f = open("/etc/hosts")
print("hosts file exists")
except FileNotFoundError:
print("no hosts file")
python3 check_hosts.py
hosts file exists
Scopes
Local - внутри функции
Enclosing - внутри фукнции, которая вызвала функцию
Global - во всем модуле
Built-in - встроено в Python
LEGB
Ссылки на Local уничтожаются после выполнения функции
Рассмотрим функцию fetch_words()
из статьи про
docstring
url, story, story_words, line, line_words, word - это локальные переменные
def fetch_words(url): """Fetch a list of words from a URL. Args: url: The URL of a UTF-8 text document. Returns: A list of strings containing the words from the document """ # PEP 257 # story = urlopen("http://sixty-north.com/c/t.txt") story = urlopen(url) story_words = [] for line in story: line_words = line.decode("utf8").split() for word in line_words: story_words.append(word) story.close() return story_words def print_items(story_words): """Print items one per line. Args: An iterable series of printable items. """ for word in story_words: print(word) def main(url): words = fetch_words(url) print_items(words) if __name__ == "__main__": main(sys.argv[1])
Разберем поведение глобальных переменных
count = 0 def show_count(): print(count) def set_count(c): count = c show_count() # 0 set_count(5) show_count() # 0
0 0
Изменить поведение функции можно с помощью global
count = 0 def show_count(): print(count) def set_count(c): global count count = c show_count() # 0 set_count(5) # Now affects global variable show_count() # 5
0 5
Полезные ссылки
codingbat.com
projecteuler.net
codeabbey
reddit
pythonchallenge
Указание кодировки
Сверхкраткий курс Python
learnxinyminutes.com/docs/python/
uuid
Пример создания строки из uuid
import uuid def str_uuid(): return str(uuid.uuid4()) print("name" + str_uuid()) print("name" + str_uuid()) print("name" + str_uuid()) print("name" + str_uuid()) print("name" + str_uuid())
name8873e1d2-b3c2-497a-952d-89bd3a658edc name4168f752-c676-4740-a12a-b7f7cd07fd2d namebf2e4954-644d-4c6e-be41-de9c3c2809b8 named53dbef3-b798-4af4-a3be-61ad349eac30 name79765d36-cb5c-4514-b6c7-3f9c5779e44a
Про uuidgen можете прочитать здесь
os
Библиотеку os я отнёс в раздел «Основы» по не совсем обычной причине. Без неё можно прекрасно изучать Python и писать сложные скрипты, но только до выхода за рамки IDE или плоской архитектуры. Уверенное понимание основ путей до файлов (os.path) и различных проверок существования, а так же других операций над файлами значительно упростит переход от разработки в вакууме до запуска скриптов в боевых условиях.
Менеджер контекста
Без знаний о том как сделать свой менеджер контекста также можно спокойно использовать Python. Эта статья показывает тем, кому любопытно что может быть под капотом у with насколько просто это делается.
Основы Python | |
Type Hints | |
__future__ | |
configparser | |
Менеджер контекста | |
docstring | |
#!: Shebang | |
Объекты | |
Итерация | |
os | |
pathlib |