python - 涉及类的递归函数
问题描述
def check_classes(cls):
if len(cls.__bases__) == 0:
return []
else:
test_list = []
for x in range(len(cls.__bases__)):
test_list += [cls] + check_classes(cls.__bases__[x])
for x in cls.__bases__:
return test_list + [x]
我目前有一个递归函数,它将一个类作为其参数并返回所有基类的列表。这工作正常,但它在列表中有许多重复的类。我想返回一个集合而不是一个列表,并且想知道如何更改代码来做到这一点。
解决方案
Python 有一个内置set
类型可以消除重复:
def get_bases(obj):
bases = {obj} # new set including only obj
if not(obj.__bases__): # technically redundant - iter is a noop on empty collections
return bases
else:
for x in obj.__bases__:
bases.update(get_bases(x)) # update set - automatically eliminates duplicates
return bases
这段代码一开始就避免了添加许多重复项。但是,在set
多重继承的情况下仍然会消除重复。
class A: ...
class B1(A): ...
class B2(A): ...
class C(B1, B2): ...
print(get_bases(C))
# {<class '__main__.C'>, <class '__main__.B1'>, <class 'object'>, <class '__main__.B2'>, <class '__main__.A'>}
Python 是 Python,已经有一些东西可以做到这一点:
>>> C.__mro__
(__main__.C, __main__.B1, __main__.B2, __main__.A, object)
如果您只关心基础,请使用__mro__
. 它的顺序还表示如何使用多个碱基执行查找。
这种搜索的一种稍微不同的方法是使用 aset
来跟踪重复项,但使用 alist
来存储元素:
def get_bases(obj, _dupes=None):
_dupes = _dupes if _dupes is not None else set()
bases = [obj] # new list including only obj
_dupes.add(obj)
for x in obj.__bases__:
if x not in _dupes:
bases.extend(get_bases(x, _dupes)) # update set - automatically eliminates duplicates
return bases
这使用 a_dupes: set
检查您是否已经访问过课程。它不会消除您添加两次的类,而是首先添加一次。给定许多元素,此检查Aset
比 a 更快。list
但是,您需要list
保留顺序。
推荐阅读
- javascript - 映射对象的 javascript 查找值,它是数组的数组
- c# - 如何使用 Twilio 异步发送 whatsapp 消息
- arrays - 将字符串解析为 bash 中包含空元素的数组
- amazon-quicksight - 日内频率的 QuickSight 电子邮件报告
- sql - MS Access 表单绑定到 ADO 记录集
- java - 凯撒密码移位后恢复原字
- python - 来自 Splinter 的 UnboundLocalError?
- android - 如何在 Android Studio 中使用概述的 Material 图标?
- node.js - Node.js 和 CPU 缓存利用率
- sql - SQL中的UPDATE语句一半工作一半不做任何事情