• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Problem z importami w pythonie

Cloud VPS
0 głosów
500 wizyt
pytanie zadane 17 czerwca 2023 w Python przez whiteman808 Mądrala (5,010 p.)
zamknięte 18 czerwca 2023 przez whiteman808

Hej,

Poniższy kod nie chce mi działać:

# example_shop/example_shop.py
from ui.menu import Menu, UserChoice, quit_menu, do_nothing_choice
from ui.shop import ShopUI
from shop.shop import Shop


def main() -> None:
    shop = Shop()
    shop_ui = ShopUI(shop)
    main_menu = Menu('Main menu', items=(
        UserChoice('Product list', shop_ui.list_products),
        UserChoice('Shopping cart', do_nothing_choice),
        UserChoice('Your orders', do_nothing_choice),
        UserChoice('Quit', quit_menu)
    ))
    main_menu.loop()


if __name__ == '__main__':
    main()


# example_shop/ui/mwnu.py
import enum
from typing import Callable, Iterable, Sequence, NamedTuple, Optional
from user_input import read_number


@enum.uniqueclass BannerStyle(enum.IntEnum):
    FRAME_BOX = enum.auto()
    HASH = enum.auto()


class UserChoice(NamedTuple):
    name: str    invoke: Callable[[], Optional[bool]]

    def __str__(self) -> str:
        return self.name


def format_choices(choices: Sequence[UserChoice]) -> Iterable[str]:
    for idx, item in enumerate(choices, 1):
        yield f'{idx}) {item}'def read_choice(choices: Sequence[UserChoice]) -> UserChoice:
    prompt = '\n'.join((*format_choices(choices),
                        'Your choice (enter an integer): '))
    while True:
        index = read_number(prompt, int) - 1        if 0 <= index < len(choices):
            return choices[index]
        print('Choice out of range.')


class Menu(NamedTuple):
    title: str    items: Sequence[UserChoice]
    banner_style: BannerStyle = BannerStyle.FRAME_BOX

    def print_banner(self) -> None:
        top_char, edge_char = None, None        match self.banner_style:
            case BannerStyle.FRAME_BOX:
                top_char = '-'                edge_char = '|'            case BannerStyle.HASH:
                top_char = '#'                edge_char = '#'        print(top_char * (len(self.title) + 4))
        print(f'{edge_char} {self.title} {edge_char}')
        print(top_char * (len(self.title) + 4))

    def loop(self) -> None:
        while True:
            self.print_banner()
            choice = read_choice(self.items)
            if choice.invoke():
                break            print()


def wait_menu() -> None:
    input("Press the enter...")


def quit_menu() -> bool:
    return Truedef do_nothing_choice() -> None:
    """    The replacement function for lambda: None in UserChoice,    where UserChoice is the Menu element.    """    print('No action defined.')
    wait_menu()

# example_shop/ui/shop.py
from example_shop.shop.shop import Shop
from .menu import wait_menu


class ShopUI:
    def __init__(self, shop: Shop):
        self.shop = shop

    def list_products(self):
        if self.shop.available_products:
            print("Available products:")
            for idx, product in enumerate(self.shop.available_products):
                print(f"{idx}) {product.name}")
        else:
            print("No such any products")
        wait_menu()

# example_shop/shop/shop.py
from .products import Product
from .users import User


class Shop:
    def __init__(self):
        self.available_products = []
        self.users = []

    def count_product(self, product: Product):
        return self.available_products.count(product)

    def create_user(self, user: User):
        self.users.append(user)

    def remove_user(self, user: User):
        self.users.remove(user)

    def add_product(self, product: Product, qty=1):
        for _ in range(qty):
            self.available_products.append(product)

    def remove_product(self, product: Product):
        self.available_products.remove(product)

Błąd:

/home/lester29/PycharmProjects/example_shop/venv/bin/python /home/lester29/PycharmProjects/example_shop/example_shop/example_shop.py 
Traceback (most recent call last):
  File "/home/lester29/PycharmProjects/example_shop/example_shop/example_shop.py", line 2, in <module>
    from ui.shop import ShopUI
  File "/home/lester29/PycharmProjects/example_shop/example_shop/ui/shop.py", line 1, in <module>
    from example_shop.shop.shop import Shop
  File "/home/lester29/PycharmProjects/example_shop/example_shop/example_shop.py", line 2, in <module>
    from ui.shop import ShopUI
ImportError: cannot import name 'ShopUI' from partially initialized module 'ui.shop' (most likely due to a circular import) (/home/lester29/PycharmProjects/example_shop/example_shop/ui/shop.py)

Process finished with exit code 1

Po zmianie w example_shop/ui/shop.py pierwszej linijki na from ..shop.shop import Shop mam błąd

/home/lester29/PycharmProjects/example_shop/venv/bin/python /home/lester29/PycharmProjects/example_shop/example_shop/example_shop.py 
Traceback (most recent call last):
  File "/home/lester29/PycharmProjects/example_shop/example_shop/example_shop.py", line 2, in <module>
    from ui.shop import ShopUI
  File "/home/lester29/PycharmProjects/example_shop/example_shop/ui/shop.py", line 1, in <module>
    from ..shop.shop import Shop
ImportError: attempted relative import beyond top-level package

Process finished with exit code 1

Pomoże ktoś?

 

komentarz zamknięcia: użyłem importów bezwzględnych

2 odpowiedzi

+1 głos
odpowiedź 18 czerwca 2023 przez Dzango111 Użytkownik (670 p.)
Bo źle importujesz "most likely due to a circular import" co znaczy że jeśli masz 2 pliki: A oraz B, to A importuje z B, a B z A, robią to w kółko i tadam, masz błąd.

"from ..shop.shop import Shop

ImportError: attempted relative import beyond top-level package"

Mi się wydaje że ten błąd ten całkiem klarowny i jasny i wystarczy użyć sekundy googla: https://stackoverflow.com/questions/30669474/beyond-top-level-package-error-in-relative-import

Nawiasem mówiąc nikt nie ma szklanej kuli - nie wiadomo jaką masz strukturę katalogów, trudno tu coś doradzić...
0 głosów
odpowiedź 18 czerwca 2023 przez KateF Lubelski Szef Nowicjusz (240 p.)

Nie wiem jak wygląda struktura katalogów u ciebie ale spróbuj zainporotwać paczki z pomocą importlib np spróbuj:

 

cos = importlib.util.spec_from_file_location("nazwa modulu", "C:\\cokolwiek.py")

paczka = spec.loader.load_module()

komentarz 18 czerwca 2023 przez Dzango111 Użytkownik (670 p.)
A po co importlib? Z tego co mi wiadomo to importliba się używa do dynamicznych importów, w tym przypadku po prostu autor źle importuje... (most likely due to a circular import)

Podobne pytania

0 głosów
1 odpowiedź 4,042 wizyt
pytanie zadane 28 października 2019 w Python przez Slimcio Nowicjusz (150 p.)
0 głosów
2 odpowiedzi 421 wizyt
pytanie zadane 29 lutego 2016 w C i C++ przez Einstein21 Obywatel (1,420 p.)
0 głosów
0 odpowiedzi 494 wizyt
pytanie zadane 1 lipca 2019 w Python przez Ventre90 Obywatel (1,170 p.)

93,487 zapytań

142,420 odpowiedzi

322,772 komentarzy

62,903 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Kursy INF.02 i INF.03
...