in my project, I have 3 separated files as mainly. My project directory
Directory/
|-main.py
|-scrape/
|--ScrapeFactory.py
|--ScrapeFromAmazon.py
ScrapeFactory.py includes
from abc import ABC, abstractmethod
from .ScrapeFromAmazon import ScrapeFromAmazon
class Scrape(ABC):
def __init__(self):
print("ScrapeFactory initialized")
"""Abstract Factory Interface"""
@abstractmethod
def create_scrape_products_from_category(self, url, header):
pass
class ScrapeFactory(ABC):
"""
The factory represents combination of scrape product
from category and scrape product from product detail page.
"""
@abstractmethod
def create_scrape_products_from_category(self) -> Scrape:
"""
Returns a new scrape product from
category belonging to this factory.
"""
pass
Also, ScrapeFromAmazon.py includes
from bs4 import BeautifulSoup
import requests
import pandas as pd
import numpy as np
from .ScrapeFactory import ScrapeFactory
class ScrapeFromAmazon(ScrapeFactory):
"""
Factory aimed at scraping products from Amazon
"""
def calculate_iterate_page_count(self):
response = requests.get(self.url, headers=self.header)
soup = BeautifulSoup(response.content, 'html.parser')
product_number_div = soup.find('div', class_='paginatorStyle-OQbSBb_oQve3e_k9LEg5').text
product_number = product_number_div.split(" ")[3]
if product_number.find("+"):
product_number = product_number[:len(product_number)-1]
self.iterate_page_count = int(int(product_number) / 48)
My python version:
Python 3.12.2
When i run the code, I have error:
ImportError: cannot import name 'ScrapeFactory' from partially initialized module 'scrape.ScrapeFactory' (most likely due to a circular import)
How to fix it?
I tried to init.py,
You are encountering a circular import.
ScrapeFactory.py
is importing ScrapeFromAmazon
, but ScrapeFromAmazon.py
is also importing from ScrapeFactory.py
.
This causes a circular dependency which python cannot resolve.
The best practices is to structure your project such that circular imports are not needed. In your case, ScrapeFactory.py
should not need to import ScrapeFromAmazon
.
If for some reason the circular import is required, you can delay the import to when a specific method is called.
class ScrapeFactory(ABC):
@abstractmethod
def some_method(self) -> None:
from .ScrapeFromAmazon import ScrapeFromAmazon
# ...