12
$\begingroup$

Platform = Ubuntu Linux 64 bit, Blender 2.77a

When creating models using bpy-based python scripting, there many times I need to type in the same code in Blender's python console; every time I invoke a new blender session.

For example if something is wrong with objects, I type the following:

for object in bpy.data.object:
    print(object.name + " is at location " + str(object.location)) 

I would like to put this in an xxx.py file I create in a documents folder so when I need to execute it in the Blender python console at each Blender session, all I would need to do is run the .py file ; this will save a lot of repetitive typing.

How do I do this?

Sam

$\endgroup$
1
  • 3
    $\begingroup$ Note, Blender comes with a template to do just this: Text Editor -> Templates -> Python -> Script Stub $\endgroup$ Commented Apr 20, 2016 at 8:55

3 Answers 3

13
$\begingroup$

This is the equivalent to running the script directly, referencing a scripts path from a 2 line text-block.

filename = "/full/path/to/myscript.py"
exec(compile(open(filename).read(), filename, 'exec'))

You might want to reference a script relative to the blend file.

import bpy
filepath = bpy.path.abspath("//myscript.py")
exec(compile(open(filepath).read(), filepath, 'exec'))
$\endgroup$
2
  • $\begingroup$ Thank you so much Smart Gnan Online!! This is a great forum! $\endgroup$ Commented Apr 20, 2016 at 8:28
  • $\begingroup$ More concise exec invocation: exec(open(filepath).read()) $\endgroup$ Commented Oct 14, 2024 at 13:52
4
$\begingroup$

Using blender's text editor you can open a script file to read and edit it. The text editor also has a "Run Script" button to easily run the script you are editing.

An open text file can also be run within the python console with

exec(compile(bpy.data.texts['Text'].as_string(), 'textblock', 'exec'))

this has an advantage when debugging as the variables in the script will remain available in the console after it has been run.

Some time back I started using an addon posted on blender artists that adds a menu to the console which lets you run any open text block in blender's python console. You gave me an idea to expand it a bit by adding another menu made from script files in a directory, the addon will now also list the files within a specific directory which will be loaded and run when chosen. You can download the updated addon here.

$\endgroup$
1
  • $\begingroup$ thanks for sharing that Idea! It fills in the gap between developing a full blown operator and just an expression typed into the console. Perfect for those quick-n-dirty snippets and stuff which lives just for some weeks, during the work on one scene, but is not worth elaborating into a full-blown piece of code $\endgroup$ Commented Feb 11, 2019 at 1:40
2
$\begingroup$

Here are two variations on the answers given by Patan and sambler that some may prefer.

Variant of Sambler's answer

If you care about in-Python-console logging, but not availability/persistence of variables, then this approach is a slightly simpler alternative to sambler's answer: (run this in the Python console)

bpy.data.texts["NameOfScript"].as_module()
Variant of Patam's answer

If you care about in-Python-console logging, but not availability/persistence of variables, then this approach is an alternative to Patam's answer: (use this as your in-Blender "launcher" script)

import sys
import bpy

# this code block will redirect calls to print() to show up in the Python-console panel
class StdOutOverride:
    def write(self, text):
        sys.__stdout__.write(text) # also send to standard-output (can comment this out)
        if text != '\n': # ignore extra stdout.write('\n') call at end of each print()
            for line in text.replace('\t', '    ').split('\n'):
                for area in bpy.context.screen.areas:
                    if area.type == 'CONSOLE':
                        with bpy.context.temp_override(area=area):
                            bpy.ops.console.scrollback_append(text=line, type='OUTPUT')
sys.stdout = StdOutOverride()

filename = "/full/path/to/myscript.py"
exec(compile(open(filename).read(), filename, 'exec'))

I prefer this last approach myself, as it lets you get logging in the Python console, while still being able to use the convenient "Play" button in the script-panel's toolbar. (and this way there's less conflict, in case variable-names in the script overlap with whatever code I may be iterating on in the Python console)

$\endgroup$
1
  • $\begingroup$ This is great! I love not having to look at the console output in a separate window. But the feedback doesn't show up in the python console until the script has finished running, which makes it less useful for long scripts (e.g. looping through a series of renders). I was able to get more updates using bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1) but that comes with performance issues and throws a warning each update. Are there any other methods to updating the python console in ~realtime? $\endgroup$ Commented Nov 30, 2023 at 20:04

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.