gpt4 book ai didi

python - 如何在 python 中找到几种类型的最近共同祖先(基本类型)?

转载 作者:太空宇宙 更新时间:2023-11-03 14:36:08 24 4
gpt4 key购买 nike

我需要找到一组类的最后一个共同祖先,以便返回该类型。

上下文,我正在做一些相当复杂的元编程,涉及重载 numpy 功能。 (不要问)我有一个函数的参数数量可变,我使用这些信息将其类型提取到一个集合中(过滤掉不相关的类型)我需要弄清楚类型树最下面的是什么所有类型共享相同的基类型。我有一些第一次尝试,但我被多重继承等绊倒了。

第一关:

def lca_type(types):
if len(types) == 1:
return types.pop()
filtered_types = set()
for type in types:
if not any(issubclass(type, x) for x in types):
filtered_types.add(type)
if len(filtered_types) == 1:
return filtered_types.pop()
# TODO: things get tricky here

考虑以下类层次结构:

class A(object):
pass
class B(A):
pass
class C(A):
pass
class D(A):
pass
class B1(B):
pass
class B2(B):
pass
class BC(C, B1):
pass
class CD(C, D):
pass
class D1(D):
pass
class BD(B, D):
pass
class B1_1(B1):
pass

预期结果:

lca_type({A,BD}) == A
lca_type({C}) == C
lca_type({B1,B2}) == B
lca_type({{B1_1, D}) == A
lca_type({CD, BD}) == D
lca_type({B1_1, BC}) == B1

最佳答案

您可以使用每个类的mro 方法来获取祖先类的列表。将祖先列表映射到 collections.Counter 以便您可以在它们上使用 & 运算符来获取共同祖先,同时保持键顺序,有效地模拟获取有序的交集套。然后根据聚合的 Counter 对象的键对祖先序列使用 next 函数来获取最近的祖先:

from functools import reduce
from operator import and_
from collections import Counter

def lca_type(classes):
return next(iter(reduce(and_, (Counter(cls.mro()) for cls in classes))))

所以下面的表达式都是True:

lca_type({A, BD}) == A
lca_type({C}) == C
lca_type({B1, B2}) == B
lca_type({B1_1, D}) == A
lca_type({CD, BD}) == D
lca_type({B1_1, BC}) == B1
lca_type({B1_1, BC, BD}) == B

请注意,键顺序仅针对 Python 3.7+ 保留,因此对于以前的 Python 版本,您可以将 Counter 替换为 collections.OrderedDict 的子类,该子类重用Counter 的属性改为:

from functools import reduce
from operator import and_
from collections import Counter, OrderedDict
import collections

collections.Counter = Counter = type('Counter', (OrderedDict,), dict(vars(Counter)))

def lca_type(classes):
return next(iter(reduce(and_, (Counter(cls.mro()) for cls in classes))))

关于python - 如何在 python 中找到几种类型的最近共同祖先(基本类型)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58290137/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com