Python:特殊な型を作成するためのサブクラス `type`(例:「intのリスト」)

StackOverflow https://stackoverflow.com/questions/6332342

  •  27-10-2019
  •  | 
  •  

質問

特殊な型を作成できるクラスを作成するために、typeをサブクラス化しようとしています。例えばListType ジェネラコディセタグプレ

ただし、このListOfIntがインスタンスの作成に使用されることはありません。他のタイプと比較するために操作できるtypeのインスタンスとして使用するだけです...特に、私の場合、入力のタイプに応じて適切な操作を検索する必要があり、タイプが必要ですより正確なものを含めるため(list of intXML stringなど)。

これが私が思いついたものです: ジェネラコディセタグプレ

上記のコードでは、abcの使用は明らかではありません...ただし、上の例のようにサブクラスのListTypeを記述したい場合は、便利になります...

基本的な機能は実際に機能します: ジェネラコディセタグプレ

しかし、tSpzTypeのインスタンスであるかどうかを確認しようとすると、Pythonがおかしくなります: ジェネラコディセタグプレ

pdb.pm()で何が起こっているのかを調べたところ、次のコードでエラーが発生することがわかりました: ジェネラコディセタグプレ

WeIrD ?!明らかに議論があります...それで、それはどういう意味ですか?何か案が ? abcを誤用しましたか?

役に立ちましたか?

解決 3

kindall からのコメントのおかげで、コードを次のようにリファクタリングしました: ジェネラコディセタグプレ

したがって、基本的に、SpzTypeabc.ABCMetaのサブクラスになり、 subclasshook はインスタンスメソッドとして実装されます。それはうまく機能し、(IMO)エレガントです!!!

編集:難しいことがありました... __subclasshook__はclassmethodである必要があるため、classmethod関数を手動で呼び出す必要があります...そうしないと、__subclasshook__を実装したい場合は機能しません。

他のヒント

あなたが何を達成したいのかよくわかりません。たぶん、collectionsを直接使用するのではなく、abcモジュールを使用する方が良いでしょうか?

ジェネリックコレクションクラスの詳細については、 PEP 3119

あなたがやりたいことのようなことは、おそらく次のようなクラスファクトリ関数を使用してより簡単に行うことができます。少なくとも私にとっては、操作しようとしているさまざまなレベルをまっすぐに保つことがより簡単になります。 ジェネラコディセタグプレ

ここでは、dictをキャッシュとして使用しているため、要素タイプと機能の特定の組み合わせに対して同じクラスオブジェクトを取得できます。これにより、listOf(int) is listOf(int)は常にTrueになります。

これは、どのクラスでも機能する他の回答のデコレータバージョンです。デコレータは、目的の属性を持つ元のクラスのサブクラスを返すファクトリ関数を返します。このアプローチの良いところは、メタクラスを義務付けていないことです。そのため、必要に応じて、競合することなくメタクラス(ABCMetaなど)を使用できます。

基本クラスがメタクラスを使用する場合、そのメタクラスは生成されたサブクラスをインスタンス化するために使用されることにも注意してください。必要に応じて、目的のメタクラスをハードコーディングするか、メタクラスをテンプレートクラスのデコレータにするデコレータを作成することができます...それはずっと下のデコレータです!

存在する場合、クラスメソッド__classinit__()はファクトリに渡された引数を渡されるため、クラス自体が引数を検証してその属性を設定するコードを持つことができます。 (これは、メタクラスの__init__()の後に呼び出されます。)__classinit__()がクラスを返す場合、このクラスは生成されたクラスの代わりにファクトリによって返されるため、この方法で生成プロシージャを拡張することもできます(たとえば、型チェックリストクラスの場合)。 、アイテムを要素タイプに強制変換する必要があるかどうかに応じて、2つの内部クラスのいずれかを返すことができます。

__classinit__()が存在しない場合、ファクトリに渡される引数は、新しいクラスのクラス属性として設定されるだけです。

タイプが制限されたコンテナクラスを作成するのに便利なように、機能dictとは別に要素タイプを処理しました。合格しなかった場合は無視されます。

以前と同様に、ファクトリによって生成されたクラスはキャッシュされるため、同じ機能を持つクラスを呼び出すたびに、同じクラスオブジェクトインスタンスを取得できます。 ジェネラコディセタグプレ

タイプ制限(実際にはタイプ変換)リストクラスの例: ジェネラコディセタグプレ

新しいクラスの生成: ジェネラコディセタグプレ

次にインスタンス化します: ジェネラコディセタグプレ

または、クラスを作成して1つのステップでインスタンス化する: ジェネラコディセタグプレ

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top