Python3 类型系统:在参数中调用特定属性?

Python3 Type System: Call for a specific attribute in argument?

假设我有一个函数要为一组完全不同的对象创建,这些对象来自不同的库,但具有相同的进程属性:

def get_foo(fooable, fooer):
  return fooer.foo(fooable)

这是任何 OOP 语言中的一个有用函数,它允许定义对象必须支持的特定接口...

在python的类型提示系统中,如果fooer没有属性foo,我是否可以声明函数将失败?

# in psuedo code
def get_foo(fooable, fooer: Type.has_attr('foo')):
   return fooer.foo(fooable)

Python 在 collections.abc. This is implemented by using ABC metaclasses, specifically defining the __instancecheck__() and/or __subclasscheck__() methods on a metaclass 中原生定义了类似于接口的东西。你可以做类似的事情:定义一个像接口一样的抽象基元类:

>>> class FooableMeta(abc.ABCMeta):
...     def __instancecheck__(self, instance):
...         return (
...             hasattr(instance, 'foo')            # has a .foo
...             and callable(instance.foo)          # .foo is callable
...             and not isinstance(instance, type)  # is an instance, not a class
...         )
... 
>>> class Fooer(metaclass=FooableMeta):
...     def __init__():
...         raise NotImplementedError()
...     def foo():
...         raise NotImplementedError()
... 
>>> class Foo:
...     def foo():
...         print("foo")
... 
>>> isinstance(Foo(), Fooable)
True
>>> class Bar:
...     def bar():
...         print("bar")
... 
>>> isinstance(Bar(), Fooable)
False

您现在可以根据相同的原则使用 Fooable 进行类型提示。