-4

I'm trying to create a function dispatching in Python to have different "overloads" for types I don't necessarily have access to in the current library.

What I know about these types are their attributes, e.g. through hasattr.

from functools import singledispatch

@singledispatch
def fun(value):
    # do something with value

@fun.register(MyType)
def _(value):
    # do something specific for MyType with value

Again MyType isn't something defined anywhere, but any type that verifies having certain attributes.

wjandrea
  • 28,235
  • 9
  • 60
  • 81
  • 2
    What's the question? – ruohola Dec 20 '22 at 22:01
  • 1
    [`Protocol`](https://docs.python.org/3/library/typing.html#typing.Protocol) with `runtime_checkable` decorator? – STerliakov Dec 20 '22 at 22:24
  • @SUTerliakov, didn't know about Protocol, thx. I tried but could not get it to work. I would have expected it to. I don't quite understand the docs on method resolution order so do not have an explanation as to why it does not. – The Lazy Graybeard Dec 21 '22 at 00:41

1 Answers1

0

The Protocol class enables an interesting approach. (thx @SUTerliakov).

from typing import Protocol, runtime_checkable

# Define protocols which identify objects having specific attributes.
# We need to test for instances at runtime.

@runtime_checkable
class FooProtocol(Protocol):
    foo: str

@runtime_checkable
class BarProtocol(Protocol):
    bar: str

Define a function which 'dispatches` according to supported protocol

def explicit_dispatch(thing):
    if isinstance(thing, FooProtocol):
        print('implements FooProtocol')
    elif isinstance(thing, BarProtocol):
        print('implements BarProtocol')
    else:
        print('neither FooProtocol nor BarProtocol')

Create objects of 'unknown' type.

from dataclasses import dataclass
# dataclass enforces the setting of attributes

@dataclass
class FooObject:
    foo: str

@dataclass
class BarObject:
    bar: str

isFooObject = FooObject('foo')
isBarObject = BarObject('bar')
isObject    = object()

Confirm function identifies instances of unknown classes.

explicit_dispatch(isFooObject)
explicit_dispatch(isBarObject)
explicit_dispatch(isObject)

prints out...

implements FooProtocol
implements BarProtocol
neither FooProtocol nor BarProtocol

Protocols don't work with singledispatch. You'll have to decide for yourself whether or not this is compatible with your coding style.

  • Although Protocols look to be useful towards your goal, this does beg the question of whether there is a good rationale for why the library you are using does not provided access to the classes in the first place. – The Lazy Graybeard Dec 21 '22 at 16:15