我有一个基类,其中包含数字属性,这些属性在初始化时简单地作为字典传递给它,然后添加到实例的字典中:
class baseclass(object):
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
def calcValue(self):
return sum(vars(self).values())
现在,我从该类中获取了一个废弃的类,该类为该类添加了其他属性,例如;
class childclass(baseclass):
def __init__(self, stringValue, **kwargs):
super(childclass, self).__init__(kwargs)
self.name = stringValue
现在,我想在我的基类中有一个函数,该函数仅对添加到该类的所有属性进行迭代,而不是对作为子属性添加的所有属性进行迭代。例如,如果我创建一个子类的实例,如下所示:
instance = childclass("myname", a=1, b=2, c=3)
然后调用calcValue方法,它应该返回1 + 2 + 3 = 6
instance.calcValue()
但是由于vars(self)将返回完整的字典,不包括childclass属性中的字符串,因此当然不能添加该字符串。有没有一种方法只能访问属于各自已删除类的实例的属性?
答案 0 :(得分:2)
您正在将所有属性作为普通值存储在实例的__dict__
上。这意味着没有任何进一步的提示,它们之间就无法区分了。
Python有两种机制以特殊方式处理属性。如果您要在类本身的基类中声明属性,然后在__init__
方法中初始化它们的值,则可以对基类的__dict__
进行内省(而不是实例的{ {1}}或同一类中的__dict__
属性。
不过,就像在示例中一样,一个简单的事情是使用特殊属性来记录添加在基类上的属性,然后将其作为属性的名称来源进行查询:
__annotations__
答案 1 :(得分:1)
一种简单,安全且有效的方法(但会增加开销)是将基类属性存储在不同的属性中,并使用__getattr__
来为其服务:
class BaseClass(object):
def __init__(self, **kwargs):
self._attribs = kwargs
def __getattr__(self, name):
try:
return self._attribs[name]
except KeyError:
raise AttributeError("object {} has no attribute {}".format(type(self).__name__, name))
def calcValue(self):
return sum(self._attribs.values())
我通常会尽量避免使用__getattr__
,因为它会使代码难以检查和维护,但是由于您的类已经没有确定的API,因此在这里并没有多大区别。