# How can a Method from a startup Script be invoked?

This is a follow up of How could a single Python script run when Blender is started?.

Simply adding a method to a newly created file in Blender\scripts\startup didn't work:

Warning! 'C:\Program Files\Blender Foundation\Blender\2.68\scripts\startup\global.py' has no register function, this is now a requirement for registerable scripts.


I used snippets from:

The script current looks like (Uses Ctrl-R to toggle between rendered and textured mode in Cycles) and adds a dump method I really need):

import bpy

class U(bpy.types.Operator):
bl_idname = "object.util"
bl_label = "Toggle Render Mode"

def execute(self, context):
# bpy.ops.sculpt.sculptmode_toggle()
for area in bpy.context.screen.areas:
if area.type == 'VIEW_3D':
if area.spaces[0].viewport_shade == 'RENDERED':
else:
return {'FINISHED'}

def dump( obj, ctx="", level=0):
for attr in dir(obj):
print( "%s.%s = %s" % (ctx, attr, getattr(obj, attr)))

self.layout.operator(U.bl_idname)

def register():
bpy.utils.register_class(U)

wm = bpy.context.window_manager
km = wm.keyconfigs.addon.keymaps.new(name='Object Mode', space_type='EMPTY')
kmi = km.keymap_items.new(U.bl_idname, 'R', 'PRESS', ctrl=True, shift=False)

def unregister():
bpy.utils.unregister_class(U)

wm = bpy.context.window_manager
for km in addon_kmaps:

if __name__ == "__main__":
register()


The toggle button works, but how can the dump() method be invoked from the python console? I noobishly tried U.dump(obj) and bpy.U.dump(obj)

EDIT:

I finally modified the existing scripts/modules/console_python.py and added (starts add line 100):

# weak! - but highly convenient
namespace["C"] = bpy.context
namespace["D"] = bpy.data
namespace['dump'] = bpy.types.OBJECT_OT_util.dump # my one

• Better not call the module global.py since global is a Python keyword and it would make importing and working with this module from another script impossible. – ideasman42 Sep 7 '13 at 21:37
• I think the unintuitive part is that a class (Operator) gets reduced to a single operation, like a function. So then how do you make classes and use polymorphism and encapsulation? My advice is to make more operators call other modules from there. – Ben L Apr 22 '14 at 19:20

Operator types are automatically added to bpy.types on registration.

This is how a method on an operator your register can be called.

bpy.types.OBJECT_OT_util.dump(bpy.context.object)


Note that it is very rare to ever access operator types like this, its more of an internal implementation detail.

normally you would access the operator via bpy.ops.object_utils() but this is only for calling the operator and won't expose its original class.

### Suggested alternative

In this case I would suggest not to having dump() as an operator class method at all. If you have a function that can run outside of the operator, you're better off having it as a utility function in a module other scripts can import and use, then have the both the operator and external scripts use it.

my_module.py:

def dump(...):
... do stuff ...

class MyOperator(Operator):
...
def execute(self, context):
dump()


So now any script can do:

import my_module
my_module.dump()


This way we bypass Blender/Python API internals where its not helpful and let Python modules interact as they would typically (outside of Blender).

It seem what your really after is a way to define your own convenience imports/variables. Looking at scripts/modules/console_python.py, I came up with the following hack (save as startup script for use):

import inspect
from functools import wraps
from pprint import pprint
from console_python import replace_help
import console_python

@wraps(inspect.getmembers)
def getmembers(object, predicate=None):
pprint(inspect.getmembers(object, predicate))

@wraps(replace_help)
def custom_convenience(namspace):
"""Add custom convenience definitions."""
replace_help(namspace)
namspace["getmembers"] = getmembers

def register():
console_python.replace_help = custom_convenience

def unregister():
console_python.replace_help = replace_help


• Thanks for your time, I didn't know that this will be complicated, I currently get "AttributeError: 'module' object has no attribute 'getmembers'" I need to read up more documentation. – stacker Sep 7 '13 at 20:11
• This is doing some interesting stuff, but not sure its really the most direct solution to the question. – ideasman42 Sep 8 '13 at 3:38