gpt4 book ai didi

python - 按对象的类型排序

转载 作者:太空宇宙 更新时间:2023-11-04 08:22:22 25 4
gpt4 key购买 nike

我有代码在模块加载时静态注册 (type, handler_function) 对,结果是这样的字典:

HANDLERS = {
str: HandleStr,
int: HandleInt,
ParentClass: HandleCustomParent,
ChildClass: HandleCustomChild
}

def HandleObject(obj):
for data_type in sorted(HANDLERS.keys(), ???):
if isinstance(obj, data_type):
HANDLERS[data_type](obj)

其中 ChildClass 继承自 ParentClass。问题在于,由于它是一个字典,因此未定义顺序 - 但我如何内省(introspection)类型对象以找出排序键

结果顺序应该是子类,然后是父类(super class)(首先是最具体的类型)。例如。 strbasestring 之前,ChildClassParentClass 之前。如果类型不相关,那么它们相对于彼此的位置并不重要。

最佳答案

如果您知道自己总是在处理新式类:

def numberofancestors(klass):
return len(klass.mro())

或者,如果您担心混合中可能有旧式类:

import inspect

def numberofancestors(klass):
return len(inspect.getmro(klass))

然后,无论哪种情况,

sorted(HANDLERS, key=numberofancestors, reversed=True)

会给你你需要的东西(你不需要 .keys() 部分)。

@Ignacio 关于拓扑排序的建议在理论上是正确的,但是由于给定一个类,您可以轻松快速地获得其前身的数量(又名“祖先”......如果你是你的祖先之一;-),有了这些 numberofancestors 函数,我的方法就更实用了:它依赖于一个明显的事实,即任何派生类至少比它的任何一个多一个“祖先”基类,因此,使用此 key=,它将始终在其任何基类之前排序。

不相关的类可能以任意顺序结束(就像它们可能以拓扑排序一样),但您已经明确表示您不关心这一点。

编辑:OP 在以下关于对多重继承案例的最佳支持的评论线程中沉思,提出了一个与问题中嵌入的“预排序”的原始想法截然不同的想法,但他关于如何实现这个彻底的想法的建议并不是最佳的:

[h for h in [HANDLERS.get(c) for c in type(obj).mro()] if h is not None][0]

这个想法很好(如果对多重继承支持有兴趣的话)但最好的实现可能是(Python 2.6 或更高版本):

next(Handlers[c] for c in type(obj).mro() if c in Handlers)

通常,adict.get(k) and check for not Noneif k in adict: adict[k] 快,但这不是特别正常这种情况是因为使用 get 需要构建一个“假的”单项列表并在其上“循环”以模拟赋值。

更一般地说,通过推导构建整个列表只是为了获取其第 [0] 项是多余的工作——在 genexp 上调用的 next 内置函数的作用更多就像 first 一样,“给我 genexp 的第一项”,除此之外不做任何额外的工作。如果 listcomp/genexp 为空,它会引发 StopIteration 而不是 IndexError,但这通常不是问题;您还可以为 next 添加第二个参数,如果 genexp 为空,则用作“默认值”。

在 2.5 和更早的版本中,你必须使用 (thegenexp).next() 来代替(并且没有办法给它一个默认参数),但是虽然在语法上有点不那么 Shiny ,但它更或在语义和速度方面等同于 2.6 及更高版本的结构。

我很高兴在评论中继续讨论,因为我认为得出的结论是有值(value)的并且可能有用(尽管可能不是在 OP 应用程序的确切环境中,多重继承实际上可能不是问题)。

关于python - 按对象的类型排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2926522/

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