如何确定属性是位于原始类还是继承类?

时间:2017-02-28 08:29:39

标签: python python-3.x attributes

在下面的代码中:

.header_links li:hover {
     cursor: pointer;
     background-color: white;
     color: black;
 }

对于“a”和“b”,可以同时访问.header_links li:hover { cursor: pointer; background-color: white; color: black !important; } class Klass_1: a = 1 class Klass_2(Klass_1): b = 2 k = Klass_2() k.ak.b

如何确定属性是否位于原始类hasattr(k, ...)或继承的类True中?

2 个答案:

答案 0 :(得分:6)

您必须检查MRO中每个类的__dict__个对象(您可以在此处使用vars()函数来使代码更清晰):

def class_for_attribute(instance, attribute_name):
    for cls in type(instance).mro():
        if attribute_name in vars(cls):
            return cls

演示:

>>> class_for_attribute(k, 'a')
<class '__main__.Klass_1'>
>>> class_for_attribute(k, 'b')
<class '__main__.Klass_2'>

答案 1 :(得分:1)

您可以搜索类对象或其超类的__dict__属性。这是一个通用功能:

In [23]: def find_origin(instance, arg):
             if arg in type(instance).__dict__:
                 return 'class'
             elif any(arg in c.__dict__ for c in type(instance).__bases__):
                 return 'super class'
             return "doesn't exist"
   ....: 

In [24]: 

In [24]: find_origin(k, 'a')
Out[24]: 'super class'

In [25]: 

In [25]: find_origin(k, 'b')
Out[25]: 'class'

In [26]: find_origin(k, 'd')
Out[26]: "doesn't exist"

正如@Martijn Pieters所提到的,为了搜索更深层次的超类,您需要使用类obejct的mro属性而不是__bases__。作为一种更加pythonic的方式,您可以在next()函数中使用生成器表达式:

In [38]: def find_origin(instance, arg):
             return next((c for c in type(instance).mro() if arg in c.__dict__), "doesn't exist")
   ....: 

In [39]: find_origin(k, 'a')
Out[39]: __main__.Klass_1

In [40]: find_origin(k, 'b')
Out[40]: __main__.Klass_2

In [41]: find_origin(k, 'c')
Out[41]: "doesn't exist"