Python提供了一些可以用來代替networkx的內省工具。 的__subclasses__
方法返回給定類的直接subclasess的列表:
In [36]: Root.__subclasses__()
Out[38]: [__main__.DataSet1a, __main__.DataSet1b]
In [61]: DataSet2.__subclasses__()
Out[61]: [__main__.DSet3a, __main__.DSet3b, __main__.DataSet3a4a]
In [62]: DataSet3a4a.__subclasses__()
Out[62]: []
的__bases__
屬性返回類的鹼(直接父類):
In [63]: DataSet3a4a.__bases__
Out[63]: (__main__.DSet3a, __main__.DataSet2, __main__.DSet4a)
的__bases__
屬性提供回答關於 的第二個問題如何找到創建數據集的輸入。
要回答第一個問題,你可以使用__subclasses__
和__bases__
到 建立自己的穿越功能:
import collections
class Root(object): pass
class DataSet1a(Root): pass
class DataSet1b(Root): pass
class DataSet2(DataSet1a): pass
class DataSet2b(DataSet1b): pass
class DSet3a(DataSet2): pass
class DSet3b(DataSet2): pass
class DSet4a(DataSet2b): pass
class DSet4b(DataSet2b): pass
class DataSet3a4a(DSet3a, DataSet2, DSet4a): pass
def visit(cls):
seen = set([cls])
queue = collections.deque(cls.__subclasses__())
while queue:
subcls = queue.popleft()
if subcls in seen: continue
# check that all its bases have been seen
for base in subcls.__bases__:
if base not in seen:
# if a base has not been seen, push subcls to the back of the queue
queue.append(subcls)
break
else:
# all the bases of subcls have already been seen
seen.add(subcls)
yield subcls
# add all the subclasses of subcls to the queue
queue.extend(subcls.__subclasses__())
for cls in visit(Root):
print(cls.__name__)
產生
DataSet1a
DataSet1b
DataSet2
DataSet2b
DSet3a
DSet3b
DSet4a
DSet4b
DataSet3a4a