クラススーツとスーツの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。
このissubclass()
のようにassert issubclass(suit, Suit)
を使用できます。
インスタンスがある場合はisinstance
を使用でき、クラスがある場合はissubclass
を使用できます。通常、それは悪い考えだと思いました。通常、Pythonでは、オブジェクトが何かを実行できるようにしようとすることで、オブジェクトが何かを実行できるかどうかを判断します。
issubclass(sub, sup)
ブール関数は、指定されたサブクラスsub
が実際にスーパークラスsup
のサブクラスである場合にtrueを返します。
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)
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)
Python 3.5.2。でテスト済み.
組み込みのissubclassを使用できます。しかし、ダックタイピングを使用できるため、型チェックは通常不要であると見なされます。
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