15
$\begingroup$

This is quite a theoretical question.

A simple function can remain inside an add-on text file. But what if you have many functions and your text file gets very long. Would it be better to split each function into logical segments lets say one file for modifiers, one file for mesh editing and such and then have one add-on file that calls / loads the code from those text files?

Or, is it better to keep everything in one file?

Are there facts I should be aware of to help me make a choice?

$\endgroup$
5
  • $\begingroup$ Organise them when it gets too long, and scrolling and looking for specific things is tedious. There is no one good way, it all depends on how each coder likes to work ... make those rules work in your favor as you go along cause you nv know how big a code will get when you first started with a small idea. $\endgroup$
    – hawkenfox
    Jan 8, 2016 at 7:01
  • $\begingroup$ My main curiosity was regarding performance, having to read all the files. Also the GitHub point is very valid to consider. $\endgroup$ Jan 8, 2016 at 18:10
  • $\begingroup$ If your main curiosity is performance then state that in the question! :) $\endgroup$
    – zeffii
    Jan 8, 2016 at 18:17
  • $\begingroup$ performance can be measured in various ways, execution speed, or 'how much time does the coder waste trying to add / fix code ' $\endgroup$
    – zeffii
    Jan 8, 2016 at 18:18
  • $\begingroup$ Agreed should have. Still all the replies are useful to me. $\endgroup$ Jan 8, 2016 at 18:18

3 Answers 3

18
$\begingroup$

In my opinion you should always use multiple files for non-trivial addons (e.g. more than one operator).

I agree that it can be complicated in at first and I have to admit that it took me quite some time until I was able to create multi-file addons in a nice way. BUT, a few months ago I developed an addon template for my Code Autocomplete addon that allows you to create multi-file addons very easily. Without having to care about reloading etc.

Since then I always use this template. Even as large addons as Animation Nodes and Code Autocomplete use it (and some others as well, e.g. this one).

Here is how I setup a new addon:

  1. Create a new folder in Blenders addons directory. It's not super important but I suggest to use a name that can be a python identifier and all lower case.

  2. Inside of this folder I create a _ init _.py file with this content.

  3. Create a developer_utils.py file with this content.

  4. Setup a git repository in that folder.

That's it. You can simply create more .py files in the folder now and all of them will be loaded and reloaded automatically. If you define operators, panels, ... inside of one of these files they will be registered as well (by the bpy.utils.register_module(_ name _) statement in the main file). Ah and don't forget to create a _ init _.py file in each subdirectory. I generally keep them empty.

The Code Autocomplete addon can do the first 3 steps for you.

http://code-autocomplete-manual.readthedocs.org/en/latest/addon_development.html

So why should you use multiple files:

  • Much better support by version control systems like GIT.
  • The dependencies in your code are much clearer, because you have to import functions you want to use in a file. That makes refactoring much easier.
  • Easier to extend without cluttering existing code.
  • Better separation between parts of you addon like operators and ui.
  • Makes it possible to write reusable modules.
  • Easier to manage in modern code editors, because most of them use a folder as project (I personally use Atom atm and like it very much!).

In summary: I only see benefits in using multi-file addons and using the template I developed most of the difficulties are gone.

$\endgroup$
2
  • 1
    $\begingroup$ thanks for your sharing! But how should I install the add on? Simply by putting the directory in the Blender addons one or also have I, from Blender User preferences.../add-ons/install from file, to select a file from that directory? $\endgroup$
    – iacopo
    Jan 23, 2017 at 10:21
  • $\begingroup$ regarding the example files from Jacques Lucke: please notice that in blender 2.80 module registration procedure has changed. E.g. bpy.utils.register_module was removed. Details here $\endgroup$ Dec 11, 2021 at 23:01
10
$\begingroup$

If you can - keep it single file and only when you have reasons - go multi-file.

Benefits of single-file:

  • it requires less code
  • other people better understand it as it is less complicated
  • it works better inside Blender environment
  • there is beauty in nicely formatted single-file Blender addon. It is nicely packed together.

When to split:

  • When your addon is a larger project (50kb+) and when you are editing with external tools. When I know a function will be shared/reused I put it inside (for example) mesh_utils.py file, then such addons become multi-file in a folder and I link the function with:

    from .mesh_utils import function
    
  • I do not split the file just because the length. Having more files over one long file is no win, both are problems to deal with. When you keep your file clean and organized, even several thousand lines long files are no problem (you can also collapse things in external editors). If the file is long I put a dictionary at the top to mark where things are (mainly their order as when you write code the lines change):

    # Contents:
    #  - naming utils
    #  - constraints utils
    #  - driver/keyframe utils
    #  - opengl
    #  - operators
    #  - handlers
    #  - ui/panels
    #  - addon prefs
    #  - properties
    #  - register
    

    Inside the code I mark each category with headline like this:

    # =====================================================
    #                       OPERATORS
    # =====================================================
    

    Inside an editor with a mini-map it can be seen and also you easily notice them when scrolling through the file helping you be oriented.

    CtrlF for search in long files is your friend and a way to be fast.

    CtrlSpacebar (Autocomplete inside Text editor) lists used text in an open text file - a reason to keep your functions inside one file when working inside Blender.

In the end it's you who will determine if the code structure is good or bad. You can make terrible multi-file mess and a symphony-like single-file and vice-versa. The key is good documentation/comments and format consistency. Keep all files and addons the same structure and name everything properly so it can be searched.

$\endgroup$
2
  • 1
    $\begingroup$ Clean code and Single Responsibility Principle already reasons enough to go multifile even if you have a single button. If you have only one file, you have 2 responsibilities at the very least in it: registration of the addon and the behavior of your addon. I looked at templates in the Text Editor and it didn't look very nice even in 70 line long examples. And it didn't just not look nice, it was harder to understand because I was trying to make sense which part of the file is really a different part of the addon, and how it is supposed to be divided conceptually. $\endgroup$
    – KulaGGin
    Apr 28, 2021 at 11:59
  • $\begingroup$ I have a script with multiple functions, on buttons, that I also need to have the option to run all those functions, in a particular order, with one button press. Is there a way to do that without having to rewrite all the functions into one operator (effectively doubling the length of the script). $\endgroup$ Oct 27, 2022 at 2:21
4
$\begingroup$

single-file -- vs -- multi-file

I think if you're looking for a Blender centric answer it's a good idea to look through the scripts that come with Blender by default. The addons folder has quite a few multi-file add-ons (as directories) and only a few long .py files -- most single-file add-ons are short.

The single file approach in general is fine for non-complicated add-ons, like a few short Operators with a Menu or Panel. Historically single file add-ons where easier to download/install by Blender newcomers. When the Install from File feature was added, which takes a zip, the single file approach lost that excuse.

Remaining reasons to use the single file approach for large add-ons are down to how comfortable someone is with Python. It's easy to write single file code, but adding a directory structure does require investing time in reading / understanding how that works. Luckily, the add-on directory has many working examples to show how you might organize a multi-file add-on. So "it's difficult" is not an excuse either.


Text Editor

More important than single or multifile is what are you coding with, a Text Editor equipped with features that help you code?

  • Does your Text Editor have plugins for checking if your code conforms to Python's "pep8" style guide? For instance this screenshot shows what I get from SublimeText when I hit save on a file with many violations of pep-8.
  • Is it easy to make and trigger snippets? -- snippets are templates of reusable code which form the basis of Operators / Panels / Menus / general code patterns. Save us retyping the boilerplate.

GIT

More important still is: are you using some kind of source-code version control, (git, svn) so you can easily keep track of changes, and revert/correct with ease when code modifications cause unwanted side effects. source control systems give convenient ways to see the differences between two updates sideby side or in the form of a .diff file.

$\endgroup$
3
  • $\begingroup$ actually I do not use GIT because besides this add-on I don't think I will ever do something similar. But GIT seems to have some benefit. $\endgroup$ Jan 17, 2016 at 0:46
  • $\begingroup$ GIT isn't just used for code, but also for documentation (allows you to keep clear history of changes to a single file or directory, text or binary), I tend to give broad / general answers to benefit more potential readers. $\endgroup$
    – zeffii
    Jan 17, 2016 at 10:15
  • $\begingroup$ Ah I see - I downloaded it. I assumed it was an online versioning tool but this works local. great! no more duplicates. $\endgroup$ Jan 17, 2016 at 17:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .