← Назад к вопросам

Для чего нужна конструкция If __main__ в Python?

1.0 Junior🔥 161 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Конструкция if name == "main" в Python

Эта конструкция определяет, был ли файл запущен как самостоятельная программа или импортирован как модуль в другой файл. Это критичный паттерн для создания переиспользуемого и тестируемого кода.

Как это работает

Переменная __name__ в Python содержит:

  • "__main__" — если файл запущен напрямую
  • Имя модуля — если файл импортирован
# file.py
print(f"Значение __name__: {__name__}")

if __name__ == "__main__":
    print("Файл запущен напрямую")
else:
    print("Файл был импортирован")

Запуск напрямую:

python file.py
# Вывод:
# Значение __name__: __main__
# Файл запущен напрямую

Импорт в другой файл:

import file
# Вывод:
# Значение __name__: file
# Файл был импортирован

Основное использование: отделение логики запуска

# calculator.py

def add(a, b):
    """Сложить два числа"""
    return a + b

def subtract(a, b):
    """Вычесть два числа"""
    return a - b

def multiply(a, b):
    """Умножить два числа"""
    return a * b

# Этот блок выполнится ТОЛЬКО при прямом запуске
if __name__ == "__main__":
    print("Калькулятор")
    print(f"5 + 3 = {add(5, 3)}")
    print(f"10 - 4 = {subtract(10, 4)}")
    print(f"6 * 7 = {multiply(6, 7)}")

Использование как модуль:

# main.py
from calculator import add, subtract, multiply

result = add(10, 20)
print(f"Результат: {result}")
# Блок if __name__ == "__main__" НЕ выполнится

Практический пример: работа с БД

# database.py
import sqlite3

class Database:
    def __init__(self, db_name):
        self.connection = sqlite3.connect(db_name)
        self.cursor = self.connection.cursor()
    
    def create_table(self):
        self.cursor.execute('''
            CREATE TABLE IF NOT EXISTS users (
                id INTEGER PRIMARY KEY,
                name TEXT,
                email TEXT
            )
        ''')
        self.connection.commit()
    
    def insert_user(self, name, email):
        self.cursor.execute(
            'INSERT INTO users (name, email) VALUES (?, ?)',
            (name, email)
        )
        self.connection.commit()
    
    def get_all_users(self):
        self.cursor.execute('SELECT * FROM users')
        return self.cursor.fetchall()
    
    def close(self):
        self.connection.close()

# Код для тестирования и демонстрации
if __name__ == "__main__":
    db = Database("test.db")
    db.create_table()
    db.insert_user("Alice", "alice@example.com")
    db.insert_user("Bob", "bob@example.com")
    
    users = db.get_all_users()
    for user in users:
        print(user)
    
    db.close()

Тестирование функций

# math_utils.py

def factorial(n):
    """Вычислить факториал"""
    if n < 0:
        raise ValueError("Факториал отрицательного числа не определен")
    if n == 0 or n == 1:
        return 1
    return n * factorial(n - 1)

def is_prime(n):
    """Проверить, является ли число простым"""
    if n < 2:
        return False
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:
            return False
    return True

# Простое тестирование при запуске
if __name__ == "__main__":
    # Тесты factorial
    assert factorial(0) == 1
    assert factorial(5) == 120
    assert factorial(10) == 3628800
    print("✓ factorial тесты пройдены")
    
    # Тесты is_prime
    assert is_prime(2) == True
    assert is_prime(17) == True
    assert is_prime(1) == False
    assert is_prime(100) == False
    print("✓ is_prime тесты пройдены")
    
    print("\nВсе тесты пройдены успешно!")

API сервер с демонстрацией

# app.py
from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/api/users', methods=['GET'])
def get_users():
    return jsonify({"users": ["Alice", "Bob", "Charlie"]})

@app.route('/api/hello/<name>', methods=['GET'])
def hello(name):
    return jsonify({"message": f"Hello, {name}!"})

if __name__ == "__main__":
    # Запустить сервер только при прямом запуске
    print("Запуск Flask сервера...")
    app.run(debug=True, host='127.0.0.1', port=5000)

# При импорте в другой файл:
# from app import app
# Сервер НЕ запустится автоматически

Сложный пример: конфигурация приложения

# config.py
import os
from pathlib import Path

BASE_DIR = Path(__file__).parent
DEBUG = os.getenv('DEBUG', 'False') == 'True'
DATABASE_URL = os.getenv('DATABASE_URL', 'sqlite:///app.db')
SECRET_KEY = os.getenv('SECRET_KEY', 'dev-secret-key')

def load_config():
    """Загрузить конфигурацию из файла"""
    from configparser import ConfigParser
    config = ConfigParser()
    config.read(BASE_DIR / 'config.ini')
    return config

if __name__ == "__main__":
    # Демонстрация конфигурации
    print(f"DEBUG mode: {DEBUG}")
    print(f"Database: {DATABASE_URL}")
    print(f"Secret key: {SECRET_KEY}")
    
    config = load_config()
    print(f"\nКонфигурация загружена из файла: {config.sections()}")

Главные преимущества

1. Переиспользуемость кода:

# utils.py
def process_data(data):
    return [x * 2 for x in data]

if __name__ == "__main__":
    # Этот код выполнится только при прямом запуске
    test_data = [1, 2, 3]
    print(process_data(test_data))

# Можно импортировать в другой файл без побочных эффектов
# from utils import process_data

2. Защита от нежелательного выполнения:

# main.py
from utils import process_data
# Блок if __name__ == "__main__" в utils.py НЕ выполнится

3. Упрощение тестирования:

# feature.py
def calculate(a, b):
    return a + b

if __name__ == "__main__":
    # Ручное тестирование
    print(calculate(5, 3))

# tests/test_feature.py
from feature import calculate

def test_calculate():
    assert calculate(5, 3) == 8
    # Блок if __name__ НЕ помешает тестам

Когда это особенно важно

  • Библиотеки и модули — код не должен выполняться при импорте
  • CLI инструменты — точка входа отделена от функций
  • Многофайловые проекты — чистое разделение ответственности
  • Тестирование — функции легко импортировать в тесты
  • Production код — безопасный импорт без побочных эффектов

Заключение

if __name__ == "__main__": — это стандартный паттерн Python для:

  • Отделения исполняемого кода от функций/классов
  • Создания переиспользуемых модулей
  • Упрощения тестирования
  • Защиты от нежелательного выполнения при импорте

Это не обязательно, но критично для профессионального кода!

Для чего нужна конструкция If __main__ в Python? | PrepBro