这只是一点点好奇心。我经常发现自己更新了一个继承在子类中的类属性,我想知道其他人如何处理它。我知道我无法在__init__
中更新它们:因为它是一个类属性,我也会将它更新为超类实例。所以我通常做这样的事情:
class A(object):
attribute = {
1: 'a',
...,
5: 'e',
}
class B(A):
attribute = {
1: 'a',
...,
5: 'e',
6: 'f',
}
但是,因为我喜欢尽可能地遵循DRY原则,并且我想知道是否有人使用更优雅的方式来完成此操作而无需完全复制和粘贴属性。
如所述,这是Django表格的具体示例:
class LoginForm(AuthenticationForm):
username = forms.EmailField(label=_('Email'))
error_messages = {
'inactive': _('This account is inactive.'),
'invalid_login': _('Please enter a correct username and password. '
'Note that both fields may be case-sensitive.'),
'unconfirmed': _('Your account is not confirmed yet. Please '
'check your email and follow the instructions '
'in order to activate it.'),
}
def confirm_login_allowed(self, user):
super(LoginForm, self).confirm_login_allowed(user)
if not user.confirmed:
raise forms.ValidationError(
self.error_messages['unconfirmed'],
code='unconfirmed')
error_messages 属性继承自django.contrib.auth.forms.AuthenticationForm,但我想添加“未确认”密钥,因此我必须复制并粘贴'inactive'和'invalid_login'钥匙也是。
答案 0 :(得分:3)
如果你把它放在__init__
中,那么每个子类的实例(在这种情况下为B
)都会看到更新。如果您直接指定类,则唯一不会出现的情况是:
B.attribute[6]
# KeyError
不使用__init__
的一种方法是:
class B(A):
attribute = A.attribute.copy()
attribute.update({
6: 'f',
7: 'g',
})
print(B().attribute) # --> {1:'a', ..., 5:'e', 6:'f', 7:'g'}
print(A().attribute) # --> {1:'a', ..., 5:'e'}
需要记住的是,类的代码在创建时执行,因此您可以使用普通的Python进行调整。
答案 1 :(得分:1)
这似乎有效:
class A(object):
attribute = {
1: 'a',
5: 'e',
}
class B(A):
attribute = A.attribute.copy()
attribute[6] = 'f'
print(A.attribute) # -> {1: 'a', 5: 'e'}
print(B.attribute) # -> {1: 'a', 5: 'e', 6: 'f'}