Although this question is in the context of a Sublime Text plugin, it is actually a question about Python object orientated design.
Writing a Sublime Text plugin which contains 2 complimentary commands (with some shared functionality) has led me to a Python inheritance dilemma. Both options work perfectly well - I'm just unsure which is better OO design.
Option 1 - plugin commands use multiple inheritance:
import sublime, sublime_plugin
class CopyLine():
def copy_line(self):
sels = self.view.sel()
# Do some stuff
return line_region
class CopyLineCommand(sublime_plugin.TextCommand, CopyLine):
def run(self, edit):
line_region = self.copy_line()
# Do some stuff
class CutLineCommand(sublime_plugin.TextCommand, CopyLine):
def run(self, edit):
line_region = self.copy_line()
# Do some stuff
Option 2 - plugin commands inherit the plugin TextCommand
class from their parent:
import sublime, sublime_plugin
class CopyLine(sublime_plugin.TextCommand):
def copy_line(self):
sels = self.view.sel()
# Do some stuff
return line_region
class CopyLineCommand(CopyLine):
def run(self, edit):
line_region = self.copy_line()
# Do some stuff
class CutLineCommand(CopyLine):
def run(self, edit):
line_region = self.copy_line()
# Do some stuff
Both options have an aspect that I'm slightly uneasy about:
In Option 1 the copy_line()
method in the CopyLine
class uses methods from the sublime_plugin.TextCommand
class - e.g. the call shown to view.sel()
- even though the CopyLine
class has not inherited the sublime_plugin.TextCommand
class.
In Option 2 the CopyLine
class inherits the sublime_plugin.TextCommand
class even though it is not actually a plugin.
Which of these is better OO design? Is there an alternative design that I should use instead?
I've put the full code of both options in a GitHub Gist.
Implementing r-stein's suggestion provides a solution to the plugin inheritance dilemma by using a non-OO design.
import sublime, sublime_plugin
def copy_line(view):
sels = view.sel()
# Do some stuff
return line_region
class CopyLineCommand(sublime_plugin.TextCommand):
def run(self, edit):
line_region = copy_line(self.view)
# Do some stuff
class CutLineCommand(sublime_plugin.TextCommand):
def run(self, edit):
line_region = copy_line(self.view)
# Do some stuff
The full code is in Option_3_CopyAndCutLine.py
of this GitHub Gist.