Execute operators from Python at start up
Background Info...

Blender intentionally prevents you from manipulating the scene at startup, this is because it is rarely useful and you end up running into issues - like loading a blend file immediately overwrite any changes you have made.

Other data such as the user preferences can be manipulated since this persists across different blend files.

1. Explicit Execution

So, if you want to do this, you can use a command line argument to run a text block in your startup.blend:

blender --python-text lamp.py


Or you can reference a path directly:

blender --python /path/to/lamp.py


This way you can control if the script runs before or after loading a blend file.

# add the lamp to any blend you open
blender example.blend --python-text lamp.py

# add the lamp, then overwrite it (not useful in this case)
blender --python-text lamp.py example.blend


The main drawback for this is it needs to be added to some startup script or launcher, or manually entered into the commandline each time you start blender.



2. Using Callbacks

Heres an example of a script you can place in startup/ which adds a handler that can manipulate the scene how you like.

import bpy

def load_handler(dummy):
    bpy.ops.object.lamp_add(type='POINT', view_align=False, location=(0.0, 0.0, 0.0), rotation=(0.0, 0.0, 0.0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))

bpy.app.handlers.load_post.append(load_handler)


This is another example which keeps the handler active but only executes on new files.

import bpy
from bpy.app.handlers import persistent

@persistent
def load_handler(dummy):

    # only apply to startup
    if not bpy.data.filepath:
        return

    bpy.ops.object.lamp_add(type='POINT', view_align=False, location=(0.0, 0.0, 0.0), rotation=(0.0, 0.0, 0.0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))

bpy.app.handlers.load_post.append(load_handler)


This may seem overkill for such a simple task, but when you consider it gives you the ability to execute code on any newly loaded file, its quite flexible.