Python 检查类属性是否在给定的类中定义或派生

Python 检查类属性是否在给定的类中定义或派生,python,inheritance,python-3.x,Python,Inheritance,Python 3.x,范例 现在collect\u foo(D)返回[1,1,2,3]-1加倍,因为D从A派生而来。问题是-如何获得唯一的foos。我想到的第一件事是检查属性是否在给定的类中派生或声明——这可能吗?怎么做?检查一下 class A: foo = 1 class B: foo = 2 class C: foo = 3 class D(A, B, C): pass def collect_foo(cls): import inspect foos =

范例

现在
collect\u foo(D)
返回
[1,1,2,3]
-
1
加倍,因为
D
A
派生而来。问题是-如何获得唯一的
foo
s。我想到的第一件事是检查属性是否在给定的类中派生或声明——这可能吗?怎么做?

检查一下

class A:
    foo = 1

class B:
    foo = 2

class C:
    foo = 3

class D(A, B, C):
    pass

def collect_foo(cls):
    import inspect
    foos = []
    for c in inspect.getmro(cls):
        if hasattr(c, 'foo'):
            foos.append(c.foo)
    return foos
而不是

'foo' in c.__dict__

如果属性是在
c
本身中定义的,那么这只会产生
True

我相信这会起作用。。。查看它是否位于类的
\uuuu dict\uuu
属性中。但是,确保你真的想先这样做

例如:

hasattr(c, 'foo')
“问题是,有些属性我不想被重写,但它们混合在一起,可用于派生类”


这正是Python中名称空间混乱的作用。不应该像这样被覆盖的属性应该以两个下划线开始。这样,它们就不会被覆盖,但对于每个类都是唯一的。

我同意接受的答案,但是
@classmethod
与我的情况不匹配

我发现从基类或mix-in的上下文中检查类dict是很有用的,在这里,我只想执行一些代码路径,如果它应用于派生类,例如某个特定方法被重写

i、 (在Python 3.6中):
如果方法名称在self.\uuuuuuuu类\uuuuuuu.\uuuuuuu dict\uuuuuuuuu.keys()中:
#做点什么

我把它合理化如下

  • self
    就是这个例子
  • \uuuu class\uuuu
    是该实例的实际类型
  • 因此,dict只包含派生类中实际重写的方法

  • 这是一件令人讨厌的事。你为什么要这么做?还有,
    set(collect_foo(D))
    做你想做的事吗?我需要写大约一百个类,其中许多类都有一些特定的特性组合,比如
    Class1(Feature1,Feature2)
    Class2(Feature2,Feature1337)
    。问题是有一些属性我不想被覆盖,但混合在派生类中并可用于派生类-因此,
    功能
    类之一提供了从继承层次结构收集所有属性的方法。这并不是那么糟糕——如果某个东西是独立于实现的、独立于版本的(甚至是2.x/3.x)并且有很好的文档记录,我不会称之为讨厌的hack。如果你有一个不想覆盖的属性,为什么要定义一个同名子类的属性?(请注意,您始终可以使用
    super
    获取基类的属性。)不完全正确,但与我一直在寻找的Sven的答案非常接近。@Mikoskay:我实际上看不到我的答案有任何显著差异。请注意,如果该类有插槽,则此操作将失败,因此请检查两者。
    if name in cls.__dict__:
        # ... your code here ...
        pass