Импорт с использованием имени пакета, нарушающего сравнение перечислений в Python

#python #python-3.x #enums #module

#python #импорт #перечисления #упаковка #пакет

Вопрос:

Мы с моим другом создаем шахматные ИИ на Python, но столкнулись с загадочной проблемой с перечислениями. Мы кодируем типы элементов в перечислении следующим образом:

Piece.py:

 from enum import Enum

class PieceType(Enum):
    type_one = 1
    ...

def recognise_type(my_type):
    print("Passed ", my_type)

    if my_type is PieceType.type_one:
        print("Type One")
    else:
        print("Type not recognised")
  

Мы запрашиваем у ИИ фигуру (например, для продвижения пешки) и вызываем recognise_type:

ai.py:

 import Piece

def get_promotion():
    return Piece.PieceType.type_one
  

bug.py:

 import Piece
import ai

my_type = ai.get_promotion()
Piece.recognise_type(my_type)
  

Пока все хорошо; запущенная ошибка.py выводит следующее:

 Passed PieceType.type_one
Type One
  

Но вот в чем дело. Имя этого пакета ‘Chess’, но если в ai.py мы меняем import Piece на from Chess import Piece (например, если мы хотим поместить ai.py в другой упаковке), то что-то пойдет не так. Запущенная ошибка.теперь py выдает:

 Passed PieceType.type_one
Type not recognised
  

Что здесь происходит? Почему включение имени пакета в инструкцию import нарушает сравнение перечислений?

Комментарии:

1. Почему вы используете is для сравнения, а не == ?

2. @DanielRoseman: потому что вы можете сделать это со значениями перечисления .

Ответ №1:

Что касается Python, вы импортируете другой модуль; у вас есть Piece и у вас есть Chess.Piece . Python создаст отдельные объекты модуля для этих двух модулей, каждый с отдельным классом enum. Значения в этих классах никогда не будут проверяться как равные.

Если все ваши модули являются частью Chess пакета, вам не следует рассматривать файлы в этом пакете как модули верхнего уровня. Это означает, что вы не должны добавлять этот каталог в свой путь Python (явно или неявно, используя скрипт в этом каталоге).

Комментарии:

1. Насколько я понимаю, вы говорите, что мы должны использовать Chess. для всего нашего импорта, и таким образом мы будем использовать один и тот же объект module во всех файлах?

2. @Megdatronica: точно. Или использовать from . import Piece для использования относительного импорта. Только если Chess/ это часть вашего пути Python, вы можете импортировать другие модули в пакет, как если бы они в любом случае были пакетами верхнего уровня.

3. Спасибо, это действительно полезно!