Ved-форум поддержки
Программирование => Python => Тема начата: DigitalMag от Марта 30, 2019, 10:52:45 am
-
У меня есть класс:
class HTMLMixin:
def __init__(self, sub = 'def', cssclass = '', *args, **kwargs): # request=None,
super(HTMLForm, self).__init__(*args, **kwargs)
self.request = kwargs.pop('request', None)
self.submit = sub
self.css_class = cssclass
self.enctype = kwargs.get('enctype','')
Я от него наследуюсь:
class SignForm(AuthenticationForm, HTMLMixin):
pass
Но получаю ошибку 'SignForm' object has no attribute 'css_class'
. Получается, что SignForm не вызывает конструктор HTMLMixin автоматически?
-
В python если вы в конструкторе не переопределяете конструктор вручную, будет автоматически вызван конструктор родителя первой ветки наследования. И далее согласно последовательности __mro__. Единственное, что может вам помешать вызвать конструктор родителя - это его переопределение в классе-предке без вызова конструктора-предка, например:
class A(object): pass
class B(object):
def __init__(self):
self.b = 1
print "bbbbbbbbbbb"
class C(A,B):
def __init__(self):
super(C,self).__init__()
print "cccccccccccc"
#print self.a
print self.b
def main():
c = C()
выведет:
bbbbbbbbbbb
cccccccccccc
1
Но если мы переопределим конструктор в A без вызова super:
class A(object):
def __init__(self):
pass
то получим ошибку:
AttributeError: 'C' object has no attribute 'b'
Если же переопределить грамотно:
class A(object):
def __init__(self):
super(A,self).__init__()
print "AAAAAAAAAAAAA"
то все конструкторы вызовутся по порядку без ошибок.
Так же для 2.7 важно, чтобы все объекты в цепочке mro были наследованы от object - т.е. их классы были типами, а не экземплярами classobj. О чем я говорю:
class B:
def __init__(self):
self.b = 1
print "BBBBBBBBBBBB"
Наследование от такого класса не будет вызывать его конструктор, т.е. наследует только атрибуты класса - все методы и поля класса, но не экземпляра. Это тоже важный паттерн
-
Сделал HTMLMixin типом:
class HTMLMixin(object):
Но все равно не видит поля css_class
Если поменять их местами, то получаю ошибку на строке:
super(SignForm, self).__init__(*args, **kwargs)
super(type, obj): obj must be an instance or subtype of type
Сам конструктор HTMLMixin вызывается, но при попытке вызвать из него конструктор родителя получаю такую ошибку
-
Но все равно не видит поля css_class
Если вникнуть в суть, наверняка в цепочке наследования AuthenticationForm есть предок, который не вызывает базовый конструктор родителя - считай это определенное ограничение на множественное наследование для AuthenticationForm
Поэтому вам надо использовать class SignForm(HTMLMixin, AuthenticationForm):
Что касается другой ошибки, то я внимательно посмотрел ваш код и нашел в нем такую ошибку: ваш класс называется HTMLMixin, а в конструкторе вы вызываете HTMLForm. Это, вероятно, просто ваша опечатка.
-
Спасибо!