У меня есть эта программа, в которой я пытаюсь работать с json и посмотреть, какие таланты доступны, но когда я пытаюсь запустить таланты, я получаю ошибку при импорте

Main.py

from pygame import *
import pygame
from Talent_List import *
import requests
import json
import sys
import time


class DeepwokenBuilder:
    def __init__(self):
        self.active = True

    def start(self):
        while self.active:
            print(" Starting... welcome to the deepwoken talent checker! \n")
            self.questions()

            q = input("Would you like to continue? ")

            if q == "yes " or q == "y":
                continue

            else:
                print(" Goodbye, ending loop")
                self.active = False
                break

    def talent_reqs(self):
        pass


    def questions(self):
        flame = input("How much flamecharm do you have?\n")
        gale = input("How much galebreath do you have?\n")
        frost = input("How much frostdraw do you have?\n")
        thunder = input('How much thunder do you have?\n')

        attributes = [flame, gale, frost, thunder]

        return attributes

        def controller(self):
            pass


if __name__ == '__main__':
    Db = DeepwokenBuilder()
    Db.start()

Таланты.py

import json
from Main import DeepwokenBuilder


# make talent logic here ig

with open(r'C:\Users\Zahir\Desktop\DeepwokenBuilder\Deepwoken Builder\Talent_list.json') as f:
    Talent_list = json.load(f)


class Talents:
    def __init__(self):
        self.Talent_list = Talent_list
        self.flamecharm = Talent_list['flamecharm']
        self.galebreath = Talent_list['galebreath']
        self.frostdraw = Talent_list['frostdraw']
        self.thundercall = Talent_list['thundercall']
        self.base = Talent_list['base']


    def display_talents(self):
        db = DeepwokenBuilder()

        attributes = db.questions()
        print(attributes)

        for i, v in self.Talent_list.items():
            attunement = i
            for i, v in v.items():
                talent_name = i
                talent_req = v

                print(f"{talent_name, talent_req}, {attunement} ")
                print(attributes)

                # if attributes < whatever

tt = Talents()
tt.display_talents()

Ошибка:

ImportError: cannot import name 'DeepwokenBuilder' from partially initialized module 'Main' (most likely due to a circular import) (DeepwokenBuilder\Deepwoken Builder\Main.py)

Я пытаюсь понять, почему у меня возникает ошибка.

Как сказано в сообщении об ошибке, вы не можете использовать Main import Talents и Talents import Main. (Из вашего кода не ясно, что это происходит, но сообщение об ошибке ясно и ясно говорит об этом.) Простое решение — поместить общую зависимость в третий файл, который вы можете импортировать из обоих без циклической зависимости.

tripleee 22.05.2024 07:43

(Отдельно, код в конце Talents.py будет выполняться в тот момент, когда вы import открываете файл, что вам, вероятно, не нужно. Либо полностью отложите это на вызывающую сторону, либо поместите ее в функцию, которую вызывающая сторона сможет вызвать, когда она хочу, чтобы это произошло.)

tripleee 22.05.2024 07:46

ОТ: Вы импортируете множество модулей, которые не нужны вашей программе. Почему? Есть и другие проблемы, о которых вы узнаете, когда исправите циклический импорт.

Some programmer dude 22.05.2024 07:47

У меня там есть импортированные модули, потому что я все еще планирую их использовать.. еще не добрался до них.

Devair 22.05.2024 07:48

Эмпирическое правило: не делайте того, что вам не нужно делать. Не добавляйте сложности, дополнительный код или функции, потому что они могут вам понадобиться в будущем. Добавляйте то, что вам нужно, прямо сейчас, а будущие модули, код и т. д. оставьте на будущее, когда вы их реализуете. Чем проще ваш код, тем легче его будет поддерживать и отлаживать, а в будущем — расширять.

Some programmer dude 22.05.2024 07:56

возможно, не используйте db = DeepwokenBuilder() в def display_talents(self):, а отправьте его как параметр def display_talents(self, db): - таким образом вам не придется использовать from Main import DeepwokenBuilder в Talents.py. И не запускайте tt = Talents() tt.display_talents() в Tallents.py, а запускайте Main.py с параметрами tt = Talents(db)

furas 22.05.2024 12:16

в текущем коде вы создаете два экземпляра DeepwokenBuilder() — и это может быть неправильной идеей, потому что, когда вы устанавливаете что-то в одном экземпляре, вы не получаете это в другом экземпляре. Вам следует создать только один db = DeepwokenBuilder() и отправить его в качестве параметра в Talent(db) или в display_talents(db). Но вы должны сделать это после создания DeepwokenBuilder() — поэтому вы не можете запустить tt = Talents() непосредственно в Talents.py, но в Main.py вам нужно сделать from Talents import Talents и tt = Talents(db)

furas 22.05.2024 13:06
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
7
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

У вас проблемы с импортом, потому что у вас реальная проблема с логикой:

  1. Вы создаете два экземпляра DeepwokenBuilder(), и когда вы меняете что-то в одном экземпляре, в другом этого не будет. Вам следует создать только один DeepwokenBuilder() и отправить его в качестве параметра другому классу - как Talents(db) или tt.display_talents(db).
  2. Вы должны создать Talents() через Main.py после того, как создадите DeepwokenBuilder
    db = DeepwokenBuilder()
    tt = Talents()
    tt.display_talents(db)
    db.start()

Если вы измените его, вам не придется импортировать DeepwokenBuilder в Talents.py, и это решит проблему с partially initialized module.


Полный рабочий пример.

(PEP8: lower_case_name.py для файлов)

(PEP 8 — Руководство по стилю кода Python)

таланты.py

import json
import os

class Talents:

    def __init__(self):

        #self.path = r'C:\Users\Zahir\Desktop\DeepwokenBuilder\Deepwoken Builder\Talent_list.json'
        self.base_dir = os.path.abspath(os.path.dirname(__file__))        
        self.path = os.path.join(self.base_dir, 'Talent_list.json')
        
        #print('[DEBUG] Talents: self.path:', self.path)
        
        with open(self.path) as f:
            self.data = json.load(f)
            
        self.flamecharm = self.data['flamecharm']
        self.galebreath = self.data['galebreath']
        self.frostdraw = self.data['frostdraw']
        self.thundercall = self.data['thundercall']
        self.base = self.data['base']

    def display_talents(self, db):

        attributes = db.questions()
        print(attributes)

        for attunement, value in self.data.items():
            for talent_name, talent_req in value.items():
                print(f"{talent_name, talent_req}, {attunement} ")
                print(attributes)

                # if attributes < whatever

main.py

#import pygame   # PEP8: `import *` is not preferred
from talents import Talents  # PEP8: `lower_case_names` for files with code - `talents.py` 

class DeepwokenBuilder:
    def __init__(self):
        self.active = True

    def start(self):
        while self.active:
            print(" Starting... welcome to the deepwoken talent checker! \n")
            self.questions()

            q = input("Would you like to continue? ")
            q = q.strip().lower()
            
            #if q !== "yes" and q != "y":
            if q not in ("yes", "y"):
                print(" Goodbye, ending loop")
                self.active = False
                break

    def questions(self):
        flame = input("How much flamecharm do you have?\n")
        gale = input("How much galebreath do you have?\n")
        frost = input("How much frostdraw do you have?\n")
        thunder = input('How much thunder do you have?\n')

        self.attributes = [flame, gale, frost, thunder]

        return self.attributes


if __name__ == '__main__':
    db = DeepwokenBuilder()   # PEP8: `lower_case_names` for variables
    tt = Talents()
    tt.display_talents(db)
    db.start()

пример Talent_list.json, если кто-то захочет его протестировать

{
"flamecharm": {"A": 1, "B": 2, "C": 3},
"galebreath": {"A": 1, "B": 2, "C": 3},
"frostdraw": {"A": 1, "B": 2, "C": 3},
"thundercall": {"A": 1, "B": 2, "C": 3},
"base": {"A": 1, "B": 2, "C": 3}
}

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