Is is bad design for a parent class's method in Python to produce instances of its children?
Question: I am doing some work with the Wikipedia category graph (using Python 3.5), and
have run into a design problem.

I have a base class Page, which defines some methods common to both articles
and categories, as well as classes for Article and Category, which inherit
from Page.

The problem is that each of these classes are quite large, so ideally I'd like
them in separate modules within a package. However, since any page on
Wikipedia (i.e. both articles and categories) can itself have categories, the
method to return the categories of a page is defined in the base Page class.
This means that the Page class depends on Category. However, since Category
depends on Page, this is a circular dependency so the only way it will work
without scoped imports is by defining both Category and Page in the same
module.

This really comes down to the fact that a method of the base class produces
instances of a specific child thereof, which is not a pattern I've had cause
to use before. (As opposed to a base class generically producing instances of
whichever child is calling the method). Is there a design pattern that will
deal with this situation, or is this perhaps one of the rare cases that calls
for a scoped import?

Snippet below for a vague illustration:

    
    
    class Page(object):
    
        def categories(self):
            return [Category(title) for title in self._category_titles()]
    
    class Category(Page):
        ...
    


Answer: The problem with circular dependency hints that the classes are actually
tightly coupled, so it is better to keep them in the same module.

In my opinion you just trying to solve the problem, which is "these classes
are quite large" in a wrong way. Python modules are used to group related
classes / functions together, which is your case.

On the other hand, problem with [large
classes](https://sourcemaking.com/refactoring/smells/large-class) should be
solved by refactoring them into smaller classes / functions.

