Reputation: 254944
What is the correct way to type an "interface" in python 3?
In the following sample:
class One(object):
def foo(self) -> int:
return 42
class Two(object):
def foo(self) -> int:
return 142
def factory(a: str):
if a == "one":
return One()
return Two()
what would be the correct way to type the return value of the factory
function?
It should be something like "A type with a single method named foo
that accepts no arguments and returns an integer".
But not sure I can find how to do that.
UPD: this question is exclusively dedicated to typing.
Upvotes: 11
Views: 2371
Reputation: 95957
You could use a typing.Union
but, it sounds like you really want structural typing not nominal. Python supports this using typing.Protocol
, which is a supported part of the python type-hinting system, so mypy
will understand it, for example:
import typing
class Fooable(typing.Protocol):
def foo(self) -> int:
...
class One(object):
def foo(self) -> int:
return 42
class Two(object):
def foo(self) -> int:
return 142
def factory(a: str) -> Fooable:
if a == "one":
return One()
return Two()
x = factory('one')
x.foo()
Note, structural typing fits well with Python's duck-typing ethos. Python's typing system supports both structural and nominal forms.
Upvotes: 14
Reputation: 11100
The ->
doesn't really do much in python.
>>> def foo()->int:
... return "yeet"
...
>>> foo()
'yeet'
Similarly with denoting types in method signatures:
>>> def bar(a: int):
... print(a)
...
>>> bar("yeet")
'yeet'
The syntax is really just a means of commenting your code. Conceptually you could implement something of an interface by raising an exception in the constructor.
>>> class foo:
... def __init__(self):
... raise()
... def someFunc(self):
... return(42)
...
>>> class bar(foo):
... def __init__(self):
... self.whatEver = "idk"
...
>>> a = bar()
>>> a.someFunc()
42
>>> baz = foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __init__
TypeError: exceptions must derive from BaseException
However you will not get the benefits of type stringency that you are looking for because python isn't a strongly typed language. Edit: Python doesn't use static typing.
Upvotes: -4