I know this has been asked a couple of times, but I couldn't quite understand the previous answers and/or I don't think the solution quite represents what I'm shooting for. I'm still pretty new to Python, so I'm having a tough time figuring this out.
I have a main class that has a TON of different functions in it. It's getting hard to manage. I'd like to be able to separate those functions into a separate file, but I'm finding it hard to come up with a good way to do so.
Here's what I've done so far:
main.py
import separate
class MainClass(object):
self.global_var_1 = ...
self.global_var_2 = ...
def func_1(self, x, y):
...
def func_2(self, z):
...
# tons of similar functions, and then the ones I moved out:
def long_func_1(self, a, b):
return separate.long_func_1(self, a, b)
separate.py
def long_func_1(obj, a, b):
if obj.global_var_1:
...
obj.func_2(z)
...
return ...
# Lots of other similar functions that use info from MainClass
I do this because if I do:
obj_1 = MainClass()
I want to be able to do:
obj_1.long_func_1(a, b)
instead of:
separate.long_func_1(obj_1, a, b)
I know this seems kind of nit-picky, but I want just about all of the code to start with obj_1.
so there isn't confusion.
Is there a better solution that what I'm currently doing? The only issues that I have with my current setup are:
- I have to change arguments for both instances of the function
- It seems needlessly repetitive
I use the approach I found here It shows many different approaches, but if you scroll down to the end it the preferred method is to basically go the opposite direction of @Martin Pieter's suggestion which is have a base class that inherits other classes with your methods in those classes.
so folder structure something like:
So your base class would be:
Then your Mixin class:
Your separate methods would be located in other appropriately named files, in this example it is just _DataStore.
I am interested to hear what others think about this approach, I showed it to someone at work and they were scared by it, but it seemed to be a clean and easy way to separate a class into multiple files.
I'm actually surprised this isn't a duplicate. I saw some similar questions and I think there is nowhere a concise answer, so here is how I do it:
__init__.py
, methods are split into files by a meaningful grouping.self
and not.Suppose my class is some fitting gui (this is actually what I did this for first time). So my file hierarchy may look something like
So plot stuff will have plotting methods, fit stuff contains fitting methods, and data stuff contains methods for loading and handling of data - you get the point. By convention I mark the files with a
_
to indicate these really aren't meant to be imported directly anywhere outside the module. So_plotsuff.py
for example may look like:etc. Now the important thing is
__init__.py
:Tom Sawyer mentions PEP-8 recommends putting all imports at the top, so you may wish to put them before
__init__
, but I prefer it this way. I have to say, my Flake8 checker does not complain, so likely this is PEP-8 compliant.Note the
from ... import ...
is particularly useful to hide some 'helper' functions to your methods you don't want accessible through objects of the class. I usually also place the custom exceptions for the class in the different files, but import them directly so they can be accessed asFitter.myexception
.If this module is in your path then you can access your class with
Not completely intuitive, but not to difficult either. The short version for your specific problem was your were close - just move the import into the class, and use
and don't forget your
self
!Here is an implementation of @Martijn Pieters♦'s comment to use subclasses:
main.py
:separate.py
: