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

时间:2011-03-09 23:03:28

标签: python inheritance python-3.x

实施例

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

现在collect_foo(D)返回[1, 1, 2, 3] - 1加倍,DA推导出来。问题是 - 如何获得独特的foo。我想到的第一件事是检查属性是否在给定的类中派生或声明 - 是否可能?怎么做?

4 个答案:

答案 0 :(得分:7)

请检查

'foo' in c.__dict__

而不是

hasattr(c, 'foo')

如果在True本身中定义了属性,则只会产生c

答案 1 :(得分:5)

我相信这会奏效......看看它是否在班级的__dict__属性中。但是,请确保你真的想先这样做。

示例:

if name in cls.__dict__:
    # ... your code here ...
    pass

答案 2 :(得分:1)

“事情是有些属性我不想被覆盖但是混合在一起并可用于派生类”

这正是Python中命名空间修改的作用。不应该像这样重写的属性应该以两个下划线开头。这样他们就不会被覆盖,但每个班级都是独一无二的。

答案 3 :(得分:0)

我同意接受的答案,但@classmethod与我的情况不符......

我发现从基类或混合的上下文中检查类 dict 是有用的,其中我只想执行一些代码路径,如果它适用于派生类,例如如果覆盖了特定方法。

即。 (在Python 3.6中):
if method_name in self.__class__.__dict__.keys(): # do something

我把它合理化如下。

  1. self是实例
  2. __class__是该实例的实际类型
  3. 因此, dict 仅包含在派生类中实际覆盖的方法。