Skirrebattie Skirrebattie - 3 months ago 9
Python Question

Function annotation for subclasses of abstract class

I'm trying to use function annotations in the hope that my editor will be better at refactoring. I however am stumbling over the following problem:

I have an abstract base class Algorithm.

class Algorithm(metaclass=ABCMeta):
def __init__(self):
self.foo = 'bar'


I also have a function that uses instances of subclasses of Algorithm

def get_foo(foo_algorithm):
return foo_algoritm.foo


the input foo_algorithm can be an instance of any of the subclasses of Algorithm. How do I sensibly annotate this input? I'm looking for something along the lines off:

def get_foo(foo_algorithm: subclassof(Algorithm)):
return foo_algoritm.foo


But I couldn't find the right way to do this.

Answer

Just use Algorithm directly:

def get_foo(foo_algorithm: Algorithm):
    return foo_algoritm.foo

and automatically any instance of a subclass will be acceptable (isinstance(foo_algorithm, Algorithm) must be true, which applies to all subclasses of a baseclass).

If you can only accept classes, then use Type[Algorithm] as the type hint:

def get_foo(foo_algorithm: Type[Algorithm]):
    return foo_algoritm().foo

See the The type of class objects section of PEP 484 -- Type Hints:

Sometimes you want to talk about class objects, in particular class objects that inherit from a given class. This can be spelled as Type[C] where C is a class. To clarify: while C (when used as an annotation) refers to instances of class C, Type[C] refers to subclasses of C.

Here I called the class object, since .foo is an instance attribute according to your code example; a class derived from Algorithm would not have such an attribute itself.

Comments