【问题标题】:Type hinting values that are multiple types?类型提示值是多种类型?
【发布时间】:2020-01-17 14:39:24
【问题描述】:

我的问题与标题所暗示的不同(我不知道如何总结这个问题,所以我很难用谷歌搜索)。

我不想要 Union 类型。 Union[A, B] 表示类型可以是 A 类型,也可以是 B 类型。

我需要相反。我希望它意味着它既是 A 类型又是 B 类型,这在 python 中是可能的,因为 mixins。

也就是说,我需要键入一个函数,以便我知道传递的参数将属于具有 A 和 B 作为父级的类,因为我的函数使用来自两个 mixin 的方法。联合类型提示允许传递不应允许的具有 A 而没有 B 的东西。

例子

from typing import Union

class A(object):
    def a(self):
        return True

class B(object):
    def b(self):
        return True

class C(A, B):
    pass

def foo(d: Union[A,B]) -> bool: #need something other than Union! 
    print(d.a() and d.b())

我需要 d 成为 A 和 B。但目前它允许我发送 A 而不是 B 的东西,并且在尝试调用不存在的函数时出错

>>> foo(A())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in foo
AttributeError: 'A' object has no attribute 'b'
>>> foo(B())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in foo
AttributeError: 'B' object has no attribute 'a'
>>> foo(C())
True

我还要注意,类型不能只是d: C。这是因为有很多类都有 A 和 B,而且需要维护的 Union 会非常长。

【问题讨论】:

  • 这被称为“交集”类型(与联合类型相反),FWIW。我不认为它完全存在于类型提示系统中。这里有一些讨论:github.com/python/typing/issues/213
  • 您可以定义一个类 C,它继承自 AB 并且什么都不做,并从当前继承自 AB 的许多类中继承.但这不是一个很好的解决方案。
  • @L3viathan 是的,这看起来像是我正在走向的可悲事实。令人惊讶的是,这个功能已经讨论了 5 年,但从未实施过。如果您包含 Union,这似乎很自然。

标签: python python-3.x types type-hinting


【解决方案1】:

您可以使用下一个 OOP 方法。

  1. 创建接口——它是python中的抽象类,可以显示方法,实现具体的类。示例:

    from abc import ABC, abstractmethod
    
    class MyAB(ABC):
        @abstractmethod
        def a(self):
            pass
    
        @abstractmethod
        def b(self):
            pass
    
    
    class A(object):
        def a(self):
            return True
    
    
    class B(object):
        def b(self):
            return True
    
    
    class ConcreteClass(MyAB, A, B):
        pass
    
    
    def foo(d: MyAB):
        print(d.a() and d.b())
    
    
    c = ConcreteClass()
    
    foo(c)
    
  1. 你说 - 函数foo 中的参数d 可以使用ab 两种方法。这就是你所需要的。

【讨论】:

  • 接受,因为考虑到当前的类型提示库,这似乎是我们能做的最好的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-20
  • 2014-06-08
  • 1970-01-01
  • 2013-03-21
  • 2018-07-20
  • 2022-11-27
  • 2014-07-15
相关资源
最近更新 更多