チェックの目的は何ですかself.__class__
?抽象インターフェイスクラスを作成し、そのself.__class__
はそれ自体です。
class abstract1 (object):
def __init__(self):
if self.__class__ == abstract1:
raise NotImplementedError("Interfaces can't be instantiated")
その目的は何ですか?クラスがそれ自体のタイプであるかどうかをチェックすることですか?
コードはNLTKのコードです http://nltk.googlecode.com/svn/trunk/doc/api/nltk.probability-pysrc.html#ProbDistI
_self.__class__
_は、現在のインスタンスのtypeへの参照です。
_abstract1
_のインスタンスの場合、これは_abstract1
_クラスitselfになります。これは、抽象クラス。抽象クラスは、インスタンスを直接作成するのではなく、サブクラス化することのみを目的としています。
_>>> abstract1()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in __init__
NotImplementedError: Interfaces can't be instantiated
_
_abstract1
_のサブクラスのインスタンスの場合、_self.__class__
_は特定のサブクラスへの参照になります。
_>>> class Foo(abstract1): pass
...
>>> f = Foo()
>>> f.__class__
<class '__main__.Foo'>
>>> f.__class__ is Foo
True
_
ここで例外をスローすることは、コードの他の場所でassert
ステートメントを使用するようなものであり、愚かな間違いを防ぐことができます。
Pythonicインスタンスのタイプをテストする方法は、 type()
function を使用することです。代わりに、is
演算子を使用したidentityテストと一緒に:
_class abstract1(object):
def __init__(self):
if type(self) is abstract1:
raise NotImplementedError("Interfaces can't be instantiated")
_
type()
は_self.__class__
_よりも優先される必要があります。後者は クラス属性によって隠される可能性があるため だからです。
カスタムクラスの場合と同様に、ここでは等価テストを使用する意味はほとんどありません。基本的に、___eq__
_は基本的にアイデンティティテストとして実装されます。
Pythonには abc
と呼ばれる抽象基本クラスを定義する標準ライブラリも含まれています。メソッドとプロパティを抽象としてマークし、それらの名前をまだ再定義していないサブクラスのインスタンスの作成を拒否します。
そこに投稿したコードは何もしません。 self.__class__ == c1
は条件の一部ではないため、ブール値は評価されますが、結果は何も行われません。
抽象基本クラス自体のインスタンス化を防ぐために、self.__class__
が(ifステートメントを介して)仮説の子ではなく、抽象クラスと等しいかどうかを確認する抽象基本クラスを作成することもできます。開発者のミスによる。
何人かはそうするだろうと私は言うでしょう:
class Foo(AbstractBase):
def __init__(self):
super(Foo, self).__init__()
# ...
ベースが抽象であっても、ベースの__init__
がNotImplementedError
をスローしないようにする必要があります。ねえ、多分それは何か便利なことでもありますか?
その目的は何ですか?クラスがそれ自体のタイプであるかどうかをチェックすることですか?
はい、タイプAbstract1
のオブジェクトを作成しようとすると、その例外がスローされ、許可されていないことが通知されます。
Python 3では、type()
を使用してタイプを確認するか、__class__
を使用しても同じ結果が返されます。
class C:pass
ci=C()
print(type(ci)) #<class '__main__.C'>
print(ci.__class__) #<class '__main__.C'>
私は最近@dataclass
デコレータの implementation をチェックしました(レイモンドヘッティンガーはそのプロジェクトに直接関与しています)。型を参照するために__class__
を使用しています。
したがって、__class__
を使用することは間違いありません:)
手がかりは、クラスの名前「abstract1」とエラーにあります。これは、抽象クラス、つまりサブクラス化されることを意図したものです。各サブクラスは独自の動作を提供します。抽象クラス自体は、インターフェイス、つまりインターフェイスを実装するクラスが持つことが期待されるメソッドと引数をドキュメント化するのに役立ちます。それ自体がインスタンス化されることを意図したものではなく、テストは、クラス自体にあるのかサブクラスにいるのかを示すために使用されます。
Julien Danjouによる、この article の抽象クラスに関するセクションを参照してください。