问题:如何(在运行时)检查一个类是否是另一个类的子类?
假设我有一个西服类和西服的四个子类:Heart,Spade,Diamond,Club。
class Suit:
...
class Heart(Suit):
...
class Spade(Suit):
...
class Diamond(Suit):
...
class Club(Suit):
...
我有一个方法,该方法接收西装作为参数,这是一个类对象,而不是实例。更准确地说,它可能仅接收以下四个值之一:Heart,Spade,Diamond,Club。我该如何做出保证这种事情的断言?就像是:
def my_method(suit):
assert(suit subclass of Suit)
...
我正在使用Python 3。
Let’s say that I have a class Suit and four subclasses of suit: Heart, Spade, Diamond, Club.
class Suit:
...
class Heart(Suit):
...
class Spade(Suit):
...
class Diamond(Suit):
...
class Club(Suit):
...
I have a method which receives a suit as a parameter, which is a class object, not an instance. More precisely, it may receive only one of the four values: Heart, Spade, Diamond, Club. How can I make an assertion which ensures such a thing? Something like:
def my_method(suit):
assert(suit subclass of Suit)
...
I’m using Python 3.
回答 0
您可以使用issubclass()
像这样assert issubclass(suit, Suit)
。
You can use issubclass()
like this assert issubclass(suit, Suit)
.
回答 1
回答 2
isinstance
如果您有实例或issubclass
类,则可以使用。通常认为这是一个坏主意。通常,在Python中,您可以通过尝试对某个对象进行处理来确定该对象是否具有某种处理能力。
You can use isinstance
if you have an instance, or issubclass
if you have a class. Normally thought its a bad idea. Normally in Python you work out if an object is capable of something by attempting to do that thing to it.
回答 3
该issubclass(sub, sup)
如果给定的子类布尔函数返回真sub
不愧是超类的子类sup
。
The issubclass(sub, sup)
boolean function returns true if the given subclass sub
is indeed a subclass of the superclass sup
.
回答 4
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
minimal runnable example
Here is a more complete example with some assertions:
#!/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 upstream.
Tested in Python 3.5.2.
回答 5
您可以使用内置的issubclass。但是通常认为类型检查是不必要的,因为您可以使用鸭子类型。
You can use the builtin issubclass. But type checking is usually seen as unneccessary because you can use duck-typing.
回答 6
使用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)
Using issubclass seemed like a clean way to write loglevels. It kinda feels odd using it… but it seems cleaner than other options.
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)
回答 7
根据Python文档,我们还可以使用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
According to the Python doc, we can also use class.__mro__
attribute or class.mro()
method:
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
回答 8
#issubclass(child,parent)
class a:
pass
class b(a):
pass
class c(b):
pass
print(issubclass(c,b))#it returns true
#issubclass(child,parent)
class a:
pass
class b(a):
pass
class c(b):
pass
print(issubclass(c,b))#it returns true