2016-09-13 7 views
0

Я пытаюсь создать класс mixin, который имеет свои собственные свойства, но поскольку класс не имеет init для инициализации «скрытой» переменной за свойством.Несколько миксинов и свойств

class Software: 

    __metaclass__ = ABCMeta 

    @property 
    def volumes(self): 
     return self._volumes 

    @volumes.setter 
    def volumes(self, value): 
     pass 

class Base(object): 

    def __init__(self): 
     self._volumes = None 

class SoftwareUser(Base, Software): 

    def __init__(self): 
     super(Base, self).__init__() 

Так выше это лучшее, что я придумал, чтобы решить эту проблему, но реальность такова, что _volumes dosn't действительно принадлежат в базе. Я мог бы добавить init в класс Software, но тогда супер-вызов не будет работать на обоих микшинах.

Во-вторых, мне понадобится несколько микшинов, зависящих от входящего вызова, они всегда будут нуждаться в базе, но микшины будут меняться, поэтому мне не нужны переменные из микшинов, которые не смешиваются для этого вызова.

Есть ли способ, с помощью которого mixin может добавлять переменные в класс, если он смешивается, возможно, динамически вызывает init класса mixin ?.

Все вопросы дайте мне знать.

Благодаря

+0

Непонятно мне, что вы подразумеваете под * «Я мог бы добавить init в класс Software, но тогда супер-вызов не будет работать на обоих mixins» *. Все три класса должны правильно реализовать '__init__' и инициализировать любые необходимые им атрибуты. – jonrsharpe

+0

Итак, что я имею в виду, в приведенном выше примере добавьте инициализацию с переменной _volumes в класс программного обеспечения, но если я это сделаю, и она смешана с базовым классом, как в примере (SoftwareUser), тогда init класса Software не будет вызываться только Base init будет называться –

+0

Нет, если вы их правильно реализуете, чтобы обеспечить выполнение любых других реализаций в MRO. Только 'Base' не следует называть' super', и он должен быть * последним * унаследованным классом. – jonrsharpe

ответ

0

Да, это дико сложное. Класс (включая mixins) должен отвечать только за вызов следующей версии в MRO, а не для сортировки всех них. Попытайтесь:

class Software: 

    @property 
    def volumes(self): 
     return self._volumes 

    @volumes.setter 
    def volumes(self, value): 
     pass 

    def __init__(self): 
     self._volumes = None 
     super().__init__() # mixin calls super too 


class Base(object): 

    def __init__(self): 
     other_vars = None 


class SoftwareUser(Software, Base): # note order 

    def __init__(self): 
     super().__init__() # all you need here 
+0

Ах, спасибо, что это был недостающий кусок, я понял. это не то, что интуитивно понятно, что супер будет следовать за MRO, я ожидал, что должен наследовать базу из класса «Software», чтобы иметь возможность использовать супервызов –

+0

. Примечание: 'super(). method()' работает только в Python 3. В 2 вам нужно выполнить 'super (ThisClass, self) .method()' – justanr

0

Ok так вот что я придумал, я открыт для других ответов, если бы я сделал этот путь более сложным.

class Software: 

    @property 
    def volumes(self): 
     return self._volumes 

    @volumes.setter 
    def volumes(self, value): 
     pass 

    def __init__(self): 
     self._volumes = None 


class Base(object): 

    def __init__(self): 
     other_vars = None 


class SoftwareUser(Base, Software): 

    def _bases_init(self, *args, **kwargs): 
     for base in type(self).__bases__: 
      base.__init__(self, *args, **kwargs) 

    def __init__(self, *args, **kwargs): 
     self._bases_init(*args, **kwargs) 
Смежные вопросы