Необычный импорт класса в Python

В папке exceptions.py есть файл kubernetes.client, в котором определен класс ApiException. Поэтому я могу написать следующую строку в своем собственном файле, скажем, myfile.py и использовать ApiException для создания исключения.

Фрагмент кода some_folder.myfile.py:

from kubernetes.client.exceptions import ApiException
.....
.....
    try:
        .....
    except ApiException as e:
        .....

Это нормально.

Также в папке rest.py, присутствующей в kubernetes.client, импортируется тот же класс ApiException и возникает некоторое исключение.

Фрагмент кода kubernetes.client.rest.py:

from kubernetes.client.exceptions import ApiException
.....
.....
     if not 200 <= r.status <= 299:
         raise ApiException(http_resp=r)

Это тоже хорошо. Но я очень смущен, увидев приведенные ниже вещи, поскольку ApiException импортируется из kubernetes.client.rest в файл some_file.py (см. Ниже), а не из kubernetes.client.exceptions, где присутствует фактическое определение класса для ApiException.

Фрагмент кода some_folder.some_file.py:

from kubernetes.client.rest import ApiException
.....
.....
    try:
       .....
    except ApiException as e:
       .....

Приведенный выше код работает, но я очень удивлен. Может кто-нибудь объяснить мне, что здесь происходит. Извините, я новичок в Python.

Примечание:

  1. Класс ApiException не определен в kubernetes.client.rest, он определен только в kubernetes.client.exceptions
  2. Я искал много статей в Интернете, но не получил много информации.
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Привет, люди RPA, это снова я и я несу подарки! В очередном моем приключении о том, как создавать ботов для облегчения рутины. Вот, думаю, стоит...
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
Учебник по веб-скрапингу
Учебник по веб-скрапингу
Привет, ребята... В этот раз мы поговорим о веб-скрейпинге. Целью этого обсуждения будет узнать и понять, что такое веб-скрейпинг, а также узнать, как...
Тонкая настройка GPT-3 с помощью Anaconda
Тонкая настройка GPT-3 с помощью Anaconda
Зарегистрируйте аккаунт Open ai, а затем получите ключ API ниже.
0
0
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Имя ApiException также определено в kubernetes.client.rest, потому что оно было импортировано туда. kubernetes.client.rest использует его, значит, он там существует. Любое имя, существующее на верхнем уровне модуля, является атрибутом этого модуля и может быть импортировано откуда угодно. Неважно, как это имя должно быть определено там.

Возможно, класс следует импортировать из его канонического местоположения, где он был определен, но это не обязательно. some_folder.some_file.py может не знать, где изначально было определено исключение, если оно взаимодействует только с kubernetes.client.rest и ему просто нужно перехватывать возникающие там исключения.


Вы часто будете видеть, как этот метод используется в файлах __init__.py для простого повторного экспорта некоторых классов, определенных в подмодулях, под более простым именем, например:

# foo/__init__.py
from .submodule import Foo
from .othermodule import Bar

Это позволяет пользователям foo в from foo import Foo вместо того, чтобы делать from foo.submodule import Foo, но при этом реализация foo остается чистой и разделенной на несколько файлов.

Другие вопросы по теме