实施例
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
加倍,D
从A
推导出来。问题是 - 如何获得独特的foo
。我想到的第一件事是检查属性是否在给定的类中派生或声明 - 是否可能?怎么做?
答案 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
我把它合理化如下。
self
是实例__class__
是该实例的实际类型