最佳实践:更新/扩展子类attribu

2024-05-06 07:27:42 发布

您现在位置:Python中文网/ 问答频道 /正文

这只是一个小小的好奇。我经常发现自己在更新子类中继承的类属性,我想知道其他人是如何处理它的。我知道我不能在__init__中更新它们:因为它是一个类属性,所以我也会将它更新到超类实例。所以我通常会这样做:

class A(object):
    attribute = {
        1: 'a',
        ...,
        5: 'e',
    }

class B(A):
    attribute = {
        1: 'a',
        ...,
        5: 'e',
        6: 'f',
    }

但是,因为我喜欢尽可能地遵循干燥原则,我想知道是否有人使用更优雅的方法来实现这一点,而不完全复制和粘贴属性。你知道吗

如前所述,这是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')

错误消息属性继承自django.contrib.auth公司.表单.身份验证表单但是我想添加“unconfirmed”密钥,所以我不得不复制并粘贴“inactive”和“invalid\u login”密钥。你知道吗


Tags: self表单属性粘贴usernameloginattributeforms
2条回答

如果将它放入__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进行调整。你知道吗

这似乎奏效了:

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'}

相关问题 更多 >