Основы разработки на языке Python: от простого к сложному

Раздел: Python -> Основы разработки на Python

Написание программы на Python начинается с выбора инструментов и понимания структуры кода. В этом руководстве рассматриваются основные подходы к созданию Python-скриптов, от простейших до более организованных, с примерами и разбором типичных затруднений.

Основной подход: программа с точкой входа

Как организовать программу, чтобы её можно было использовать как скрипт и как модуль?

Стандартная практика - определить функцию main() и вызвать её внутри условной конструкции if __name__ == '__main__'. Это делает код переиспользуемым и тестируемым.

def main():
    name = input("Введите ваше имя: ")
    print(f"Привет, {name}!")

if __name__ == "__main__":
    main()

пишем программу на python (написание программы на python)

Пояснение: input() считывает строку от пользователя, f-строка подставляет значение переменной. Конструкция if __name__ == '__main__' проверяет, является ли файл основным исполняемым, а не импортированным модулем.

Типичные проблемы: IndentationError из-за неверных отступов, SyntaxError при неправильном синтаксисе f-строки (например, забытая фигурная скобка). Решение: использовать редактор с автоформатированием (например, PyCharm, VS Code) и проверять отступы (4 пробела или табуляция последовательно).

Как быстро написать одноразовый скрипт без функций?

Для небольших прототипов допустим код на верхнем уровне. Это сокращает объём, но усложняет повторное использование.

name = input("Введите ваше имя: ")
print("Привет, " + name + "!")

Пояснение: конкатенация строк через + менее удобна, чем f-строки, но работает.

Проблемы: переменные становятся глобальными, код нельзя импортировать без побочных эффектов. Решение: для серьёзных проектов использовать функцию main().

Как написать программу, принимающую параметры при запуске?

Аргументы командной строки доступны через список sys.argv. Первый элемент - имя скрипта, остальные - переданные значения.

import sys

if len(sys.argv) > 1:
    name = sys.argv[1]
else:
    name = "мир"
print(f"Привет, {name}!")

Пояснение: проверяется количество аргументов, чтобы избежать IndexError.

Проблемы: отсутствие аргументов приводит к ошибке индексации. Решение: всегда проверять len(sys.argv) или использовать модуль argparse для более сложного разбора.

Как обработать данные из внешнего файла?

Чтение файла выполняется через open() и контекстный менеджер with, который гарантирует закрытие файла.

def read_greeting(filename):
    with open(filename, 'r', encoding='utf-8') as f:
        return f.read().strip()

def main():
    try:
        greeting = read_greeting("greeting.txt")
    except FileNotFoundError:
        greeting = "Привет"
    name = input("Введите имя: ")
    print(f"{greeting}, {name}!")

if __name__ == "__main__":
    main()

Пояснение: encoding='utf-8' важно для корректного чтения кириллицы. .strip() удаляет лишние пробелы и переводы строк.

Проблемы: файл может отсутствовать (FileNotFoundError) или быть недоступным. Решение: обрабатывать исключение и задавать значение по умолчанию.

Как интегрировать внешний API в программу?

Сторонние модули, такие как requests, упрощают работу с HTTP. Предварительно модуль нужно установить через pip.

import requests

def get_user_info(username):
    url = f"https://api.github.com/users/{username}"
    response = requests.get(url)
    if response.status_code == 200:
        return response.json()
    else:
        return None

def main():
    username = input("Введите имя пользователя GitHub: ")
    info = get_user_info(username)
    if info:
        print("Имя:", info.get('name'))
        print("Репозитории:", info.get('public_repos'))
    else:
        print("Пользователь не найден")

if __name__ == "__main__":
    main()

Пояснение: requests.get() отправляет GET-запрос, .json() парсит ответ. Установка: pip install requests.

Проблемы: модуль не установлен, отсутствует интернет, неверный URL. Решение: использовать try-except для requests.exceptions.ConnectionError и проверять код ответа.

Как сделать программу устойчивой к ошибкам и записывать отладку?

Модуль logging позволяет вести журнал событий разного уровня (DEBUG, INFO, ERROR).

import logging

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

def divide(a, b):
    try:
        result = a / b
        logging.info(f"Деление {a} на {b} = {result}")
        return result
    except ZeroDivisionError:
        logging.error("Деление на ноль")
        return None

def main():
    try:
        a = float(input("Введите число a: "))
        b = float(input("Введите число b: "))
    except ValueError:
        logging.error("Введено не число")
        return
    result = divide(a, b)
    if result is not None:
        print("Результат:", result)

if __name__ == "__main__":
    main()

Пояснение: basicConfig задаёт уровень логирования и формат. ValueError обрабатывает нечисловой ввод.

Проблемы: забыто логирование исключений, неправильный формат. Решение: добавлять логирование во все критические точки, тестировать с разными входными данными.

Расширенные примеры программ

Пример 1: Калькулятор с поддержкой операций и аргументов командной строки

Программа принимает два числа и операцию через аргументы (или ввод) и выводит результат. Используется модуль argparse для гибкого парсинга.

Пример
import argparse

def calculator(a, b, operation):
    if operation == '+':
        return a + b
    elif operation == '-':
        return a - b
    elif operation == '*':
        return a * b
    elif operation == '/':
        if b == 0:
            raise ZeroDivisionError("Деление на ноль")
        return a / b
    else:
        raise ValueError(f"Неизвестная операция: {operation}")

def main():
    parser = argparse.ArgumentParser(description="Простой калькулятор")
    parser.add_argument('a', type=float, help="Первое число")
    parser.add_argument('b', type=float, help="Второе число")
    parser.add_argument('--op', '-o', default='+', help="Операция (+, -, *, /)")
    args = parser.parse_args()
    try:
        result = calculator(args.a, args.b, args.op)
        print(f"{args.a} {args.op} {args.b} = {result}")
    except (ZeroDivisionError, ValueError) as e:
        print(f"Ошибка: {e}")

if __name__ == "__main__":
    main()

Результат запуска: python calc.py 10 5 --op '*' выведет 10 * 5 = 50.0.

$ python calc.py 10 5 --op '*'
10 * 5 = 50.0
$ python calc.py 10 5 --op '/'
10 / 5 = 2.0
$ python calc.py 10 0 --op '/'
Ошибка: Деление на ноль

Пример 2: Подсчёт слов в текстовом файле с использованием функций и файлового ввода

Скрипт читает файл, считает количество слов, строк и символов. Имя файла передаётся как аргумент.

Пример
import sys

def count_stats(filename):
    try:
        with open(filename, 'r', encoding='utf-8') as f:
            text = f.read()
        lines = text.count('\n')
        if not text.endswith('\n'):
            lines += 1
        words = len(text.split())
        chars = len(text)
        return lines, words, chars
    except FileNotFoundError:
        return None

def main():
    if len(sys.argv) != 2:
        print("Использование: python wordcount.py <файл>")
        sys.exit(1)
    filename = sys.argv[1]
    stats = count_stats(filename)
    if stats is None:
        print(f"Файл '{filename}' не найден.")
    else:
        lines, words, chars = stats
        print(f"Строк: {lines}")
        print(f"Слов: {words}")
        print(f"Символов: {chars}")

if __name__ == "__main__":
    main()

Результат для файла lorem.txt с текстом из трёх строк:

$ cat lorem.txt
Привет мир
Это тестовый файл
Третья строка
$ python wordcount.py lorem.txt
Строк: 3
Слов: 6
Символов: 39

Пример 3: Работа с базой данных SQLite (создание таблицы и выборка)

Программа создаёт базу данных users.db, добавляет записи о пользователях и выводит всех пользователей старше 25 лет.

Пример
import sqlite3

def create_db():
    conn = sqlite3.connect('users.db')
    cursor = conn.cursor()
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS users (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            name TEXT NOT NULL,
            age INTEGER
        )
    ''')
    conn.commit()
    conn.close()

def insert_user(name, age):
    conn = sqlite3.connect('users.db')
    cursor = conn.cursor()
    cursor.execute('INSERT INTO users (name, age) VALUES (?, ?)', (name, age))
    conn.commit()
    conn.close()

def select_users(min_age):
    conn = sqlite3.connect('users.db')
    cursor = conn.cursor()
    cursor.execute('SELECT name, age FROM users WHERE age > ?', (min_age,))
    rows = cursor.fetchall()
    conn.close()
    return rows

def main():
    create_db()
    insert_user('Анна', 30)
    insert_user('Иван', 22)
    insert_user('Мария', 28)
    insert_user('Пётр', 19)
    
    min_age = 25
    print(f"Пользователи старше {min_age} лет:")
    for name, age in select_users(min_age):
        print(f"  {name} - {age} лет")

if __name__ == "__main__":
    main()

Результат:

Пользователи старше 25 лет:
  Анна - 30 лет
  Мария - 28 лет

Пример 4: Простое графическое приложение с Tkinter

Окно с полем ввода и кнопкой, которая выводит приветствие.

Пример
import tkinter as tk
from tkinter import messagebox

def greet():
    name = entry.get()
    if name:
        messagebox.showinfo("Приветствие", f"Здравствуйте, {name}!")
    else:
        messagebox.showwarning("Внимание", "Введите имя")

root = tk.Tk()
root.title("Приветствие")
root.geometry("300x150")

label = tk.Label(root, text="Введите ваше имя:")
label.pack(pady=10)

entry = tk.Entry(root)
entry.pack(pady=5)

button = tk.Button(root, text="Поздороваться", command=greet)
button.pack(pady=10)

root.mainloop()

После запуска появляется окно с полем ввода. При нажатии кнопки отображается диалоговое окно.

Написание программы на Python - comments

En
пишем программу на python (python)