>>> from os import PathLike
>>> class MyPath(PathLike):
... def __init__(self, prefix, path):
... self._prefix = prefix
... self._path = path
...
... def __fspath__(self):
... return self._prefix + self._path
...
>>>
>>> from pathlib import Path
>>> os.fspath(Path("test.txt"))
'test.txt'
>>> os.fspath(MyPath("https://", "test.txt"))
'https://test.txt'
-
-
Save atemate/fc828014f86d1d2feb4f19f3c9e8bb66 to your computer and use it in GitHub Desktop.
Normal "minimal" usage
>>> class Animal:
... def _say(self):
... pass
... def speak(self):
... return f"I am an animal that says '{self._say()}'"
...
>>> class Cat(Animal):
... def _say(self):
... return "meow"
...
>>> class Dog(Animal):
... def _say(self):
... return "woof!"
...
>>> d = Dog()
>>> d.speak()
"I am an animal that says 'woof!'"
>>> c = Cat()
>>> c.speak()
"I am an animal that says 'meow'"
So we're having a common abstraction Animal
with some common functionality speak()
, which internally uses an "abstract" method _say()
that defines specific narrow functionality of a child concrete class (Dog
and Cat
).
From the OOP high-level perspective, Animal
is an abstract class, it's its function that it serves to its children classes.
Normally, abstract classes should not be instantiated (i.e. there can't exist an "animal", but only a "dog" or a "cat") as the program doesn't have enough information about how the instances should behave (i.e. what should _say()
an animal, meow or bark?).
However, Python does not restrict us from doing so:
>>> a.get_sentence()
"I am an animal that says 'None'"
So usually we're creating abstract classes using the library abc
:
>>> class Animal(abc.ABC):
... @abc.abstractmethod
... def _say(self):
... pass
... def get_sentence(self):
... return f"I am an animal that says '{self._say()}'"
...
>>> a = Animal()
Traceback (most recent call last):
Cell In[20], line 1
a = Animal()
TypeError: Can't instantiate abstract class Animal with abstract method _say
>>> class Dog(Animal):
... pass
...
>>> d = Dog()
Traceback (most recent call last):
Cell In[22], line 1
d = Dog()
TypeError: Can't instantiate abstract class Dog with abstract method _say
Often, instead of @abc.abstractmethod
we're throwing an exception raise NotImplementedError("implement me")
in the abstract method:
>>> class Animal:
... def _say(self):
... raise NotImplementedError("_say()")
... def speak(self):
... return f"I am an animal that says '{self._say()}'"
...
... class Cat(Animal):
... def _say(self):
... return "meow"
...
... class Dog(Animal):
... def _say(self):
... return "woof!"
...
>>> Animal().speak()
Traceback (most recent call last):
...
NotImplementedError: _say()