今日、私はリスコフの代入原理と共分散/反変について深く掘り下げました。
そして、私は次の違いに行き詰まりました:
T = TypeVar("T", bound=Union[A, B])
T = TypeVar("T", A, B, covariant=True)
#1についての私の理解
TypeVar( 'T'、A、B)とTypeVar( 'T'、bound = Union [A、B]) の違い
この答え はT
が次のようになる可能性があることを明確に述べています
- _
Union[A, B]
_(または_Union[A, BChild]
_などのA
およびB
のサブタイプの和集合)A
(またはA
のサブタイプ)B
(またはB
のサブタイプ)
これは完全に理にかなっています。
MyFlawed#2の理解
MyPyは、制約されたTypeVarが共変であることを許可していませんか?制約されたが共変なkey-val型を持つ一般的なdictの定義
_bound=Union[A, B]
_のケースについて再度言及しますが、オプション#2、_A, B, covariant=True
_の意味は理解できません。
私はmypy
をいじってみましたが、理解できないようです。 これが何を意味するのか誰でも指摘できますか?
私は考えるそれは意味します:
A
(またはA
のサブタイプ)B
(またはB
のサブタイプ)(別名Union
ケースを上から除外します)
**編集**
コメントで尋ねられました:
それらが実際に異なると確信していますか?
違いを示すサンプルコードを次に示します。エラーは_mypy==0.770
_から発生します。
_from typing import Union, TypeVar, Generic
class A: pass
class ASub(A): pass
class B: pass
# Case 1... Success: no issues found
# T = TypeVar("T", bound=Union[A, B])
# Case 2... error: Value of type variable "T" of "SomeGeneric" cannot be "ASub"
T = TypeVar("T", A, B, covariant=True)
class SomeGeneric(Generic[T]): pass
class SomeGenericASub(SomeGeneric[ASub]): pass
_
**編集2 **
これは私が持っていたいくつかの誤解を解消しました。 A
とB
は実際には共変ではないことがわかっているため、TypeVar("T", A, B, covariant=True)
は実際には正しくありません。
_covariant=True
_構文の使用は、それらが関連している場合にのみ役立ちます。
共分散と逆分散は、オブジェクト指向とジェネリックの共通部分に関連する用語です。
この概念が答えようとしている質問は次のとおりです。
Base
とDerived
があります。List<T>
としましょう。List<Derived>
はList<Base>
が使用できる場所ならどこでも使用できるということですか。List<Base>
はList<Derived>
ができるところならどこでも使用できますか?(3)の答えが「はい」の場合、それは共分散と呼ばれ、List
をcovariance=True
として宣言するとします。 (4)の答えがtrueの場合、それは「逆分散」と呼ばれます。いずれも真でない場合、それは不変です。
境界はOOとジェネリックスの交点からも得られます。ジェネリックタイプMyTypeを定義すると、 'T'はどんなタイプでもかまわないという意味ですか?または、いくつかの制限を課すことができますTはどのようなものでしょうか?境界により、Tの上限は、たとえば、クラスDerived
であると述べることができます。その場合、Base
は 'MyType'と共に使用できません-しかしDerived
とそのすべてのサブクラスはできます。
共分散と反分散の定義は PEP-484のこのセクション にあります。