Python 在不合并文件的情况下解决循环导入
Python Resolving Circular Imports without merging files
我有一段代码定义了游戏中可能的物品类型和附魔类型。某些附魔类型彼此不兼容或与某些物品类型不兼容。我希望每个项目类型都有关于哪些附魔与其不兼容的信息,以及每个附魔都包含与其兼容的项目的信息,而不必经常查找其中一个。
items.py
:
from enum import Enum, auto
class ItemType(Enum):
PLATE = auto()
HELMET = auto()
BOOTS = auto()
SWORD = auto()
BOW = auto()
# Get compatible enchantment types
from enchantments import EnchantmentType
for it in ItemType:
it.compatible_enchantments = set(filter(lambda ench: it in ench.compatible_items, EnchantmentType))
class Item:
def __init__(self, item_type, enchantments=None):
self.type = item_type
self.enchantments = []
if enchantments:
for ench in enchantments:
self.add_enchantment(ench)
def add_enchantment(self, enchantment, i=None):
if enchantment.type not in self.compatible_enchantments:
raise ValueError(f"Enchantment {enchantment.type} is incompatible with {self.type}.")
if i is None:
self.enchantments.append(enchantment)
else:
self.enchantments.insert(enchantment, i) from enum import Enum
from items import ItemType as IT
enchantments.py
:
from enum import Enum, auto
class EnchantmentType(Enum):
ENHANCED_ARMOUR = IT.HELMET, IT.PLATE, IT.BOOTS, IT.RING
ENHANCED_DAMAGE = IT.SWORD, IT.BOW, IT.RING
YELLOW_COLOUR = ()
def __init__(self, *compatible_item_types):
self.compatible_items = set(IT) if not compatible_item_types else compatible_item_types
self.incompatible_enchantments = set()
# Fill in the incompatible enchantments
for mutualy_exclusive_group in (
{EnchantmentType.ENHANCED_ARMOUR, EnchantmentType.ENHANCED_DAMAGE}
):
for ench in mutualy_exclusive_group:
ench.incompatible_enchantments += mutualy_exclusive_group - {ench}
class Enchantment:
def __init__(self, enchantment_type, level=None):
self.type = enchantment_type
self.level = level
main.py
:
from enchantments import EnchantmentType as ET
print(ET.ENHANCED_ARMOUR.compatible_items)
print(ET.ENHANCED_DAMAGE.compatible_items)
print(ET.YELLOW_COLOUR.compatible_items)
Running this code 给我一个 ImportError
引用循环导入。
在 this answer 之后,我尝试将 from x import y
语句更改为 import x
,但仍然出现相同的错误。
我通过从 items.py
中删除 from enchantments import EnchantmentType
并移动行
暂时解决了这个问题
from enchantments import EnchantmentType
for it in ItemType:
it.compatible_enchantments = set(filter(lambda ench: it in ench.compatible_items, EnchantmentType))
变成enchantments.py
。但是,这需要任何希望获得有关附魔的正确信息的模块手动导入 enchantments.py
——仅导入 items.py
将导致所有 compatible_enchantments
为空。
有没有办法在不合并两个文件的情况下使我的循环导入工作?
为什么不在每个 ItemTypes 上设置 compatible_enchantments
,为什么不在某个地方(可能在 enchantments.py 中)有一个字典将 EnchantmentType 映射到它可以应用的有效 ItemTypes 集?
对我来说,ItemType 似乎不需要了解附魔,而是附魔需要知道它们是否可以应用于特定的 ItemType。
我有一段代码定义了游戏中可能的物品类型和附魔类型。某些附魔类型彼此不兼容或与某些物品类型不兼容。我希望每个项目类型都有关于哪些附魔与其不兼容的信息,以及每个附魔都包含与其兼容的项目的信息,而不必经常查找其中一个。
items.py
:
from enum import Enum, auto
class ItemType(Enum):
PLATE = auto()
HELMET = auto()
BOOTS = auto()
SWORD = auto()
BOW = auto()
# Get compatible enchantment types
from enchantments import EnchantmentType
for it in ItemType:
it.compatible_enchantments = set(filter(lambda ench: it in ench.compatible_items, EnchantmentType))
class Item:
def __init__(self, item_type, enchantments=None):
self.type = item_type
self.enchantments = []
if enchantments:
for ench in enchantments:
self.add_enchantment(ench)
def add_enchantment(self, enchantment, i=None):
if enchantment.type not in self.compatible_enchantments:
raise ValueError(f"Enchantment {enchantment.type} is incompatible with {self.type}.")
if i is None:
self.enchantments.append(enchantment)
else:
self.enchantments.insert(enchantment, i) from enum import Enum
from items import ItemType as IT
enchantments.py
:
from enum import Enum, auto
class EnchantmentType(Enum):
ENHANCED_ARMOUR = IT.HELMET, IT.PLATE, IT.BOOTS, IT.RING
ENHANCED_DAMAGE = IT.SWORD, IT.BOW, IT.RING
YELLOW_COLOUR = ()
def __init__(self, *compatible_item_types):
self.compatible_items = set(IT) if not compatible_item_types else compatible_item_types
self.incompatible_enchantments = set()
# Fill in the incompatible enchantments
for mutualy_exclusive_group in (
{EnchantmentType.ENHANCED_ARMOUR, EnchantmentType.ENHANCED_DAMAGE}
):
for ench in mutualy_exclusive_group:
ench.incompatible_enchantments += mutualy_exclusive_group - {ench}
class Enchantment:
def __init__(self, enchantment_type, level=None):
self.type = enchantment_type
self.level = level
main.py
:
from enchantments import EnchantmentType as ET
print(ET.ENHANCED_ARMOUR.compatible_items)
print(ET.ENHANCED_DAMAGE.compatible_items)
print(ET.YELLOW_COLOUR.compatible_items)
Running this code 给我一个 ImportError
引用循环导入。
在 this answer 之后,我尝试将 from x import y
语句更改为 import x
,但仍然出现相同的错误。
我通过从 items.py
中删除 from enchantments import EnchantmentType
并移动行
from enchantments import EnchantmentType
for it in ItemType:
it.compatible_enchantments = set(filter(lambda ench: it in ench.compatible_items, EnchantmentType))
变成enchantments.py
。但是,这需要任何希望获得有关附魔的正确信息的模块手动导入 enchantments.py
——仅导入 items.py
将导致所有 compatible_enchantments
为空。
有没有办法在不合并两个文件的情况下使我的循环导入工作?
为什么不在每个 ItemTypes 上设置 compatible_enchantments
,为什么不在某个地方(可能在 enchantments.py 中)有一个字典将 EnchantmentType 映射到它可以应用的有效 ItemTypes 集?
对我来说,ItemType 似乎不需要了解附魔,而是附魔需要知道它们是否可以应用于特定的 ItemType。