web-dev-qa-db-ja.com

あるクラスが別のクラスのサブクラスであるかどうかを(実行時に)確認するにはどうすればよいですか?

クラススーツとスーツの4つのサブクラス、ハート、スペード、ダイヤモンド、クラブがあるとします。

class Suit:
   ...
class Heart(Suit):
   ...
class Spade(Suit):
   ...
class Diamond(Suit):
   ...
class Club(Suit):
   ...

インスタンスとしてではなくクラスオブジェクトであるパラメーターとしてスーツを受け取るメソッドがあります。より正確には、ハート、スペード、ダイアモンド、クラブの4つの値のうち1つだけを受け取る場合があります。そのようなことを保証するアサーションを作成するにはどうすればよいですか?何かのようなもの:

def my_method(suit):
   assert(suit subclass of Suit)
   ...

Pythonを使用しています3。

167
snakile

このissubclass()のようにassert issubclass(suit, Suit)を使用できます。

192
user97370

issubclass(class, classinfo)

抜粋:

classclassinfoのサブクラス(直接、間接、または仮想)の場合、trueを返します。

40
Katriel

インスタンスがある場合はisinstanceを使用でき、クラスがある場合はissubclassを使用できます。通常、それは悪い考えだと思いました。通常、Pythonでは、オブジェクトが何かを実行できるようにしようとすることで、オブジェクトが何かを実行できるかどうかを判断します。

26
David Heffernan

issubclass(sub, sup)ブール関数は、指定されたサブクラスsubが実際にスーパークラスsupのサブクラスである場合にtrueを返します。

20
Jameer Mulani

Issubclassの使用は、ログレベルを記述するためのきれいな方法のように思えました。それを使用するとちょっと奇妙に感じます...しかし、他のオプションよりもきれいに見えます。

class Error(object): pass
class Warn(Error): pass
class Info(Warn): pass
class Debug(Info): pass

class Logger():
    LEVEL = Info

    @staticmethod
    def log(text,level):
        if issubclass(Logger.LEVEL,level):
            print(text)
    @staticmethod
    def debug(text):
        Logger.log(text,Debug)   
    @staticmethod
    def info(text):
        Logger.log(text,Info)
    @staticmethod
    def warn(text):
        Logger.log(text,Warn)
    @staticmethod
    def error(text):
        Logger.log(text,Error)
1
Jon Donnelly

issubclass最小限の実行可能な例

次に、いくつかのアサーションを含むより完全な例を示します。

#!/usr/bin/env python3

class Base:
    pass

class Derived(Base):
    pass

base = Base()
derived = Derived()

# Basic usage.
assert issubclass(Derived, Base)
assert not issubclass(Base, Derived)

# True for same object.
assert issubclass(Base, Base)

# Cannot use object of class.
try:
    issubclass(derived, Base)
except TypeError:
    pass
else:
    assert False

# Do this instead.
assert isinstance(derived, Base)

GitHubアップストリーム

Python 3.5.2。でテスト済み.

組み込みのissubclassを使用できます。しかし、ダックタイピングを使用できるため、型チェックは通常不要であると見なされます。

1
XORcist

Python doc によれば、class.__mro__属性またはclass.mro()メソッドも使用できます。

class Suit:
    pass
class Heart(Suit):
    pass
class Spade(Suit):
    pass
class Diamond(Suit):
    pass
class Club(Suit):
    pass

>>> Heart.mro()
[<class '__main__.Heart'>, <class '__main__.Suit'>, <class 'object'>]
>>> Heart.__mro__
(<class '__main__.Heart'>, <class '__main__.Suit'>, <class 'object'>)

Suit in Heart.mro()  # True
object in Heart.__mro__  # True
Spade in Heart.mro()  # False
0
YaOzI