web-dev-qa-db-ja.com

PythonタイピングTypeVar(A、B、covariant = True)はどういう意味ですか?

今日、私はリスコフの代入原理と共分散/反変について深く掘り下げました。

そして、私は次の違いに行き詰まりました:

  1. T = TypeVar("T", bound=Union[A, B])
  2. T = TypeVar("T", A, B, covariant=True)

#1についての私の理解

TypeVar( 'T'、A、B)とTypeVar( 'T'、bound = Union [A、B]) の違い

この答えTが次のようになる可能性があることを明確に述べています

  1. _Union[A, B]_(または_Union[A, BChild]_などのAおよびBのサブタイプの和集合)
  2. A(またはAのサブタイプ)
  3. B(またはBのサブタイプ)

これは完全に理にかなっています。


MyFlawed#2の理解

MyPyは、制約されたTypeVarが共変であることを許可していませんか?制約されたが共変なkey-val型を持つ一般的なdictの定義

_bound=Union[A, B]_のケースについて再度言及しますが、オプション#2、_A, B, covariant=True_の意味は理解できません。

私はmypyをいじってみましたが、理解できないようです。 これが何を意味するのか誰でも指摘できますか?

私は考えるそれは意味します:

  1. A(またはAのサブタイプ)
  2. 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 **

私はこれについて python/mypy#8806:Generic [T_co] erroring error when T_co = TypeVar( "T_co"、A、B、covariant = True)and pass subclass of A

これは私が持っていたいくつかの誤解を解消しました。 ABは実際には共変ではないことがわかっているため、TypeVar("T", A, B, covariant=True)は実際には正しくありません。

_covariant=True_構文の使用は、それらが関連している場合にのみ役立ちます。

共分散と逆分散は、オブジェクト指向とジェネリックの共通部分に関連する用語です。

この概念が答えようとしている質問は次のとおりです。

  1. 「レギュラー」、「オブジェクト指向」の2つのクラス、BaseDerivedがあります。
  2. ジェネリック型もいくつかあります。たとえば、List<T>としましょう。
  3. Derivedはベースのできる場所ならどこでも使用できることはわかっています。つまり、List<Derived>List<Base>が使用できる場所ならどこでも使用できるということですか。
  4. それは逆になりますか?多分それは逆方向であり、今ではList<Base>List<Derived>ができるところならどこでも使用できますか?

(3)の答えが「はい」の場合、それは共分散と呼ばれ、Listcovariance=Trueとして宣言するとします。 (4)の答えがtrueの場合、それは「逆分散」と呼ばれます。いずれも真でない場合、それは不変です。

境界はOOとジェネリックスの交点からも得られます。ジェネリックタイプMyTypeを定義すると、 'T'はどん​​なタイプでもかまわないという意味ですか?または、いくつかの制限を課すことができますTはどのようなものでしょうか?境界により、Tの上限は、たとえば、クラスDerivedであると述べることができます。その場合、Baseは 'MyType'と共に使用できません-しかしDerivedとそのすべてのサブクラスはできます。

共分散と反分散の定義は PEP-484のこのセクション にあります。

3
Roy2012