34
$\begingroup$

Simple and maybe stupid question:

I was reading this lot of time, that

"you should avoid using bpy.ops, or "instead of bpy.ops, use this and that"...

So why is that? Is that buggy, or what?

$\endgroup$
3
  • 2
    $\begingroup$ All I can think of is that it's context sensitive (they require a certain mode or certain selection). But I'll let someone more experienced answer properly. $\endgroup$
    – Greg Zaal
    Commented Sep 12, 2013 at 14:55
  • 13
    $\begingroup$ Operators often cause implicit scene updates, which can lead to quadratic runtime increase if you use them in a loop (e.g. object duplication). It may take hours to duplicate, 'cause every object in the scene is updated after each added object - and the number of objects to process increases on every iteration. An equivalent "low level" code can duplicate an object thousands of times in less than a minute and call Scene.update() once at the very end. $\endgroup$
    – CodeManX
    Commented Feb 15, 2014 at 1:07
  • $\begingroup$ Watch the example: Basically it is not practical under some sircumstances. youtube.com/watch?v=KNa5kJd2Epo&t=43m50s $\endgroup$ Commented Jan 13, 2018 at 9:02

4 Answers 4

22
$\begingroup$

Lots of bpy.ops operators depend on the context (selected objects, active shape key index, etc.), therefore I think some are more suitable to be used interactively than in a script.

I'd use bpy.ops judiciously rather than avoiding it wholesale. For example, I find creating constraint through a posebone's constraints.new easier to read, and independent from context, compared to changing context then calling pose.constraint_add_with_targets. But bpy.ops can be indispensable for some tasks like vertex group manipulation and file operation even though it means temporarily messing with context.

For me, it really depends on what you're trying to do. Before resorting to bpy.ops.*, see if the task can be accomplished in any other way. Using bpy.ops operators may not always be best, but careful application can still result in readable code and smooth user interaction.

$\endgroup$
1
  • 1
    $\begingroup$ This answer shows a comparison on how performance gets affects if you use bpy.ops $\endgroup$
    – Amir
    Commented Oct 25, 2018 at 20:15
7
$\begingroup$

I'll just quote ideasman42:

When possible I would avoid using bpy.ops, These wrap tools in a way that relies on the context and dont have a good way to pass args and return results to scripts. If there is an alternative (as with bmesh), it's better integrated into python, and you don't have to worry about active object, modes, visible layers etc.

$\endgroup$
6
$\begingroup$

Avoiding bpy.ops may boost performance of your scripts when manipulating lots of objects. See: Python performance with Blender operators

$\endgroup$
5
$\begingroup$

Apart from what's been said already, operators also create undo steps. This means that every time you execute an operator, the entire blend file is saved in memory. This is one of the reasons calling an operator is much slower than the corresponding alternative function calls.

This is also why it's a good idea to, when writing an operator, place the major part of the code into regular Python functions, and call those from the operator code. This allows others to import your module and call those functions as well, from their own code.

$\endgroup$
3
  • 1
    $\begingroup$ I'm not trying to use operators but would like to know whether the undo steps issue get resolved, even partially, if you set bpy.context.user_preferences.edit.undo_steps to 0 and bpy.context.user_preferences.edit.use_global_undo to False? $\endgroup$
    – Amir
    Commented Sep 23, 2018 at 22:54
  • 1
    $\begingroup$ One thing I usually get confused about is how I can totally avoid using operators? For instance, how can I add a cube to the scene without using bpy.ops.mesh.primitive_cube_add()? Should I manually put vertices in the scene and then make polygons? My point is it looks like there is no official guideline on how people can avoid using bpy.ops $\endgroup$
    – Amir
    Commented Sep 23, 2018 at 22:58
  • 1
    $\begingroup$ Sometimes it's not possible to avoid operators. Operators also won't create undo steps when you call them from another operator. For mesh creation it depends on your need. Calling the operator is much easier and not all that slow, but when you have to create 10000 cubes of various sizes and positions, it'll probably be better to 'manually' generate the geometry. $\endgroup$
    – dr. Sybren
    Commented Sep 24, 2018 at 10:10

You must log in to answer this question.

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