0

Let's say I have defined a subclass inherited from Path, and I want to use methods from Path. For example, Path.glob() here:

from pathlib import Path


class PhotoDir(Path):
    pass

# some custom methods

if __name__ == "__main__":

    path: str = r"Y:\Picture\2023\2023-11-03"
    photoDir: PhotoDir = PhotoDir(path)

    print(list(photoDir.glob("*")))

The result will be:

[
PhotoDir('001.jpg'), 
PhotoDir('002.jpg')
]

All methods from Path will return the subclass PhotoDir.

The result I'm expecting is:

[
Path('001.jpg'), 
Path('002.jpg')
]

And if I defined another subclass of Path Photo, the result should be:

[
Photo('001.jpg'), 
Photo('002.jpg')
]

What I have tried

I have tried override methods with super().glob(), still the same.(It makes no diff if I'm right.):

class PhotoDir(Path):
    def glob(
        self, pattern: str, *, case_sensitive: bool | None = None
    ) -> Generator[Self, None, None]:
        return super().glob(pattern, case_sensitive=case_sensitive)

I also tried Path(self).glob() in the subclass. This one works, but it seems a little bit incorrect to me.(IDK. Maybe it's right. I'm new to Python)

class PhotoDir(Path):
    def glob(
        self, pattern: str, *, case_sensitive: bool | None = None
    ) -> Generator[Self, None, None]:
        return Path(self).glob(pattern, case_sensitive=case_sensitive)

Right now I take a work around:

class PhotoDir:
    def __init__(self, *args: str | PathLike[str]) -> None:
        self.path: Path = Path(*args)

I didn't subclassing Path at all. Instead of using photoDir.glob(), I'm using photoDir.path.glob(). It works fine, but is there a smarter way to do this in Python?

3
  • Is there a reason you need plain Path objects instead of PhotoDir objects? If you are subclassing correctly, then an instance of PhotoDir should be usable anywhere an instance of Path is expected. Commented Mar 13, 2024 at 14:00
  • For example, PhotoDir.glob() returns PhotoDir('001.jpg'), which is not a dir at all. There are some operations in PhotoDir.__init__() that should not be applied to it. Commented Mar 13, 2024 at 14:51
  • Then your semantics don't allow for subclassing, as a Path represents a path to any file-system entry, not just directories. Commented Mar 13, 2024 at 15:57

1 Answer 1

0

Your PhotoDir class doesn't represent an arbitrary file path, so subclassing isn't appropriate. It represents a directory, one attribute of which is the file path that identifies it, so your final example of composition is the appropriate solution.

class PhotoDir:
    def __init__(self, *args: str | PathLike[str]) -> None:
        self.path: Path = Path(*args)

    def glob(self, *args, **kwargs):
        return self.path.glob(*args, **kwargs)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.