Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any Python equivalent to partial classes?

Using "new" style classes (I'm in python 3.2) is there a way to split a class over multiple files? I've got a large class (which really should be a single class from an object-oriented design perspective, considering coupling, etc, but it'd be nice to split over a few files just for ease of editing the class.

like image 695
Matthew Lund Avatar asked Mar 09 '12 17:03

Matthew Lund


People also ask

Does Python have partial classes?

Python comes with a fun module called functools. One of its classes is the partial class. You can use it create a new function with partial application of the arguments and keywords that you pass to it. You can use partial to "freeze" a portion of your function's arguments and/or keywords which results in a new object.

Should I put Python classes in separate files?

As Python is not an OO language only, it does not make sense do have a rule that says, one file should only contain one class. One file (module) should contain classes / functions that belong together, i.e. provide similar functionality or depend on each other. Of course you should not exaggerate this.


1 Answers

If your problem really is just working with a large class in an editor, the first solution I'd actually look for is a better way to break down the problem. The second solution would be a better editor, preferably one with code folding.

That said, there are a couple of ways you might break up a class into multiple files. Python lets you use a folder as a module by putting an __init__.py in it, which can then import things from other files. We'll use this capability in each solution. Make a folder called, say, bigclass first.

  1. In the folder put the various .py files that will eventually comprise your class. Each should contain functions and variable definitions for the eventual class, not classes. In __init__.py in the same folder write the following to join them all together.

    class Bigclass(object):      from classdef1 import foo, bar, baz, quux     from classdef2 import thing1, thing2     from classdef3 import magic, moremagic     # unfortunately, "from classdefn import *" is an error or warning      num = 42   # add more members here if you like 

    This has the advantage that you end up with a single class derived directly from object, which will look nice in your inheritance graphs.

  2. You could use multiple inheritance to combine the various parts of your class. In your individual modules you would write a class definition for Bigclass with parts of the class. Then in your __init__.py write:

    import classdef1, classdef2, classdef3  class Bigclass(classdef1.Bigclass, classdef2.Bigclass, classdef3.Bigclass):     num = 42   # add more members if desired 
  3. If the multiple inheritance becomes an issue, you can use single inheritance: just have each class inherit from another one in chain fashion. Assuming you don't define anything in more than one class, the order doesn't matter. For example, classdef2.py would be like:

    import classdef1 class Bigclass(classdef1.Bigclass):      # more member defs here 

    classdef3 would import Bigclass from classdef2 and add to it, and so on. Your __init__.py would just import the last one:

    from classdef42 import Bigclass 

I'd generally prefer #1 because it's more explicit about what members you're importing from which files but any of these solutions could work for you.

To use the class in any of these scenarios you can just import it, using the folder name as the module name: from bigclass import Bigclass

like image 93
kindall Avatar answered Sep 21 '22 19:09

kindall