In an effort to improve my (beginner) Python skills I started a pet project and now I am having trouble with circular import issues.
The pet project is a little pokemon-esque game that features among other things teams of animals wearing weapons. The relationship chain: team -> animal -> weapon (a team consists of a few animals, each animal wields a weapon). To avoid overly huge classes I decided to spread the very different classes of animal and weapon over two files and I use import to access each other. Coming from Java I like to strong-type variables, arguments, and parameters.
So stripped down a bit, my classes weapons.py and animals.py look like this:
import weapons
class Animal():
def __init__(self, name: str, level: int):
self.name: str = name
self.level: int = int
self.weapon: Weapon or None = None
def equip(self, weapon: Weapon) -> None:
self.weapon = weapon
import animals
from abc import ABC
class Weapon(ABC):
def __init__(self, type: str, power_level: float):
self.type: str = type
self.power_level: float = power_level
self.wielder: Animal or None = None
def set_wielder(wielder: Animal) -> None:
self.wielder = wielder
So when I instantiate animals, I don't want them to wield weapons right away nor do I want weapons to have owners right away. But while the relationship animal -> weapon is rather straight forward in the game, I also want to have a way to point from a weapon to the animal that owns it.
The code above causes circular import issues. When facing a different yet related issue I found the interesting __future__
module. Adding "from __future__ import annotations
" resolved my problem.
But while I am happy about my working code, I wonder whether I could have solved this issue in a more elegant manner. Whether this is smelly code. Whether there is a different solution to this all that still allows me to use typing. I am happy about any advice that improves my Python coding style (and my understanding of circular imports)