On 06/04/2016 11:55 PM, Mark Summerfield wrote:
Sometimes I want to spread a class over multiple files.

There’s and easy way to do this in Python using what's called a Mixin class and (multiple) inheritance:
  (See https://en.wikipedia.org/wiki/Mixin for more information.)

In one file, say extras.py

   class ExtraMethodsMixin:

      def extra_1(...):
          ...

      def extra_2(...):
          ...



In the main class file:

   from extras import ExtraMethodsMixin

   class MainClass(ExtraMethodsMixin):

      def __init__(...):
          ...
       # and so on


The result will be essentially the same as if all three methods were defined in MainCLass.


Gary Herron


--
Dr. Gary Herron
Professor of Computer Science
DigiPen Institute of Technology
(425) 895-4418




My primary use case is when I create a "Model" class to reflect an entire SQL 
database. I want a model instance to provide a single point of access to
  the database, but the database has many tables each requiring its own methods 
since they differ in their structure, purpose, validation needs, etc.

A secondary use case is when I create "MainWindow" classes in GUI programming 
and have lots of methods to reflect all the actions (e.g., menu options
and toolbar actions, plus interaction with the main widget(s)).

To meet these needs I've devised an approach that I think is easy to use and 
understand and which doesn't use any tricky or hard to maintain code.

My question is -- are there nicer/better ways to achieve this?

Here's a summary of my approach. A fuller discussion is on my website:
https://www.qtrac.eu/pyclassmulti.html

# Lib.py
# This provides the two functions (both decorators) used to support my approach
def add_methods_from(*modules):
     def decorator(Class):
         for module in modules:
             for method in getattr(module, "__methods__"):
                 setattr(Class, method.__name__, method)
         return Class
     return decorator

def register_method(methods): # A decorator used purely for its side-effect
     def register_method(method):
         methods.append(method)
         return method # Unchanged and not strictly necessary
     return register_method

# Model.py
# This provides my model but some methods are in separate files
import Lib
import _ModelConfig
import _ModelOutput

@Lib.add_methods_from(_ModelConfig, _ModelOutput)
class Model:
     ...
     def small_method(self):
         ...

# _ModelConfig.py # _ModelOutput has the same structure so not shown
import Lib

__methods__ = [] # self is a Model
register_method = Lib.register_method(__methods__)

@register_method
def config(self):
     ...
So, that's the overall pattern of my solution.

Is there a nicer/better way? Could I cleanly avoid the explicit imports (e.g., 
import _ModelConfig), without resorting to stack frame hacks or similar?

--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to