The advice in the documentation is to explicitly concatenate the various option lists. That said, if you want to go this route I think a custom metaclass is the right approach. Something like:
class CommandMetaclass(type): def __new__(mcl, name, bases, dct): # start with the option_list in the class we 're creating # use set() to avoid duplicates option_list = set(dct.get('option_list', tuple())) # add the options from each base class for base in bases: option_list.update(base.__dict__.get('option_list', tuple())) # replace the original option_list with our combined version dct['option_list'] = tuple(option_list) return type.__new__(mcl, name, bases, dct) class MyCommand(MyCommonOptionMixin, MyOtherCommonOptionMixin, BaseCommand): __metaclass__ = CommandMetaclass option_list = ( # Local defined options. )
Updated on Mar 16, 2020, Updated on Mar 6, 2021,By Leonardo Giordani - 27/03/2020 Updated on Apr 8, 2020
assignable reviewable item (assign_to_user, ask_review_to_user) ^ | | | pull request
assignable reviewable item (assign_to_user, ask_review_to_user) ^ | | | | + -- -- -- -- + -- -- -- -- + | | | | | | issue pull request(not reviewable)
assignable item (assign_to_user) ^ | | | | + -- -- -- + -- -- -- -- -- -- -- + | | | | | | | reviewable assignable item | (ask_review_to_user) | ^ | | | | | | issue pull request
assignable item + -- -- -- -- > reviewable item(assign_to_user) | (ask_review_to_user) ^ | ^ | | | | | | | CODE DUPLICATION | | | | + -- -- -- + -- -- -- -- -- -- -- + | | | | | | | | | | | | V | | reviewable assignable item | | (ask_review_to_user) | | ^ | | | | | | | | | | issue pull request best practice
assignable item reviewable item (assign_to_user)(ask_review_to_user) ^ ^ ^ | | | | | | | | | | | | + -- -- -- + -- -- -- -- -- -- - + + -- -- -- -- -- -- -- -- -- -- -- + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | issue pull request best practice
class Parent1():
def __init__(self): [...]
class Parent2():
def __init__(self): [...]
class Child(Parent1, Parent2):
# This inherits from both Parent1 and Parent2, which __init__ does it use ?
pass
A mixin is a class that provides method implementations for reuse by multiple related child classes. However, the inheritance is not implying an is-a relationship.,A mixin class provides method implementions for resuse by multiple related subclasses.,Typically, a child class uses multiple inheritance to combine the mixin classes with a parent class.,A mixin bundles a set of methods for reuse. Each mixin should have a single specific behavior, implementing closely related methods.
First, define a Person
class:
.wp - block - code {
border: 0;
padding: 0;
}
.wp - block - code > div {
overflow: auto;
}
.shcb - language {
border: 0;
clip: rect(1 px, 1 px, 1 px, 1 px); -
webkit - clip - path: inset(50 % );
clip - path: inset(50 % );
height: 1 px;
margin: -1 px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1 px;
word - wrap: normal;
word - break: normal;
}
.hljs {
box - sizing: border - box;
}
.hljs.shcb - code - table {
display: table;
width: 100 % ;
}
.hljs.shcb - code - table > .shcb - loc {
color: inherit;
display: table - row;
width: 100 % ;
}
.hljs.shcb - code - table.shcb - loc > span {
display: table - cell;
}
.wp - block - code code.hljs: not(.shcb - wrap - lines) {
white - space: pre;
}
.wp - block - code code.hljs.shcb - wrap - lines {
white - space: pre - wrap;
}
.hljs.shcb - line - numbers {
border - spacing: 0;
counter - reset: line;
}
.hljs.shcb - line - numbers > .shcb - loc {
counter - increment: line;
}
.hljs.shcb - line - numbers.shcb - loc > span {
padding - left: 0.75 em;
}
.hljs.shcb - line - numbers.shcb - loc::before {
border - right: 1 px solid #ddd;
content: counter(line);
display: table - cell;
padding: 0 0.75 em;
text - align: right; -
webkit - user - select: none; -
moz - user - select: none; -
ms - user - select: none;
user - select: none;
white - space: nowrap;
width: 1 % ;
}
class Person:
def __init__(self, name):
self.name = nameCode language: Python(python)
Second, define an Employee
class that inherits from the Person
class:
class Employee(Person):
def __init__(self, name, skills, dependents):
super().__init__(name)
self.skills = skills
self.dependents = dependentsCode language: Python(python)
Third, create a new instance of the Employee
class:
if __name__ == '__main__':
e = Employee(
name = 'John',
skills = ['Python Programming'
'Project Management'
],
dependents = {
'wife': 'Jane',
'children': ['Alice', 'Bob']
}
) Code language: Python(python)
To convert instances of the Employee
class to dictionaries, the Employee
needs to inherit from both DictMixin
and Person
classes:
class Employee(DictMixin, Person):
def __init__(self, name, skills, dependents):
super().__init__(name)
self.skills = skills
self.dependents = dependentsCode language: Python(python)
The following creates a new instance of the Employee
class and converts it to a dictionary:
e = Employee(
name = 'John',
skills = ['Python Programming', 'Project Management'],
dependents = {
'wife': 'Jane',
'children': ['Alice', 'Bob']
}
)
pprint(e.to_dict()) Code language: Python(python)
The __tablename__ attribute may be used to provide a function that will determine the name of the table used for each class in an inheritance hierarchy, as well as whether a class has its own distinct table.,This works because Base here doesn’t define any of the variables that MyMixin defines, i.e. __tablename__, __table_args__, id, etc. If the Base did define an attribute of the same name, the class placed first in the inherits list would determine which attribute is used on the newly defined class.,A common need when using declarative is to share some functionality, such as a set of common columns, some common table options, or other mapped properties, across many classes. The standard Python idioms for this is to have the classes inherit from a base which includes these common features.,Where above, the class MyModel will contain an “id” column as the primary key, a __tablename__ attribute that derives from the name of the class itself, as well as __table_args__ and __mapper_args__ defined by the MyMixin mixin class.
from sqlalchemy.ext.declarative
import declared_attr
class MyMixin(object):
@declared_attr
def __tablename__(cls):
return cls.__name__.lower()
__table_args__ = {
'mysql_engine': 'InnoDB'
}
__mapper_args__ = {
'always_refresh': True
}
id = Column(Integer, primary_key = True)
class MyModel(MyMixin, Base):
name = Column(String(1000))
class MyModel(Base, MyMixin):
name = Column(String(1000))
from sqlalchemy.ext.declarative
import declared_attr
class Base(object):
@declared_attr
def __tablename__(cls):
return cls.__name__.lower()
__table_args__ = {
'mysql_engine': 'InnoDB'
}
id = Column(Integer, primary_key = True)
from sqlalchemy.ext.declarative
import declarative_base
Base = declarative_base(cls = Base)
class MyModel(Base):
name = Column(String(1000))
class TimestampMixin(object):
created_at = Column(DateTime,
default = func.now())
class MyModel(TimestampMixin, Base):
__tablename__ = 'test'
id = Column(Integer, primary_key = True)
name = Column(String(1000))
from sqlalchemy.ext.declarative
import declared_attr
class ReferenceAddressMixin(object):
@declared_attr
def address_id(cls):
return Column(Integer, ForeignKey('address.id'))
class User(ReferenceAddressMixin, Base):
__tablename__ = 'user'
id = Column(Integer, primary_key = True)
class MyMixin:
@declared_attr
def type_(cls):
return Column(String(50))
__mapper_args__ = {
'polymorphic_on': type_
}
class MyModel(MyMixin, Base):
__tablename__ = 'test'
id = Column(Integer, primary_key = True)