python script to handle new mesh extruding

i working on a python real time script that run every time I extrude a face in a edit mode so i found that you can use handler to handling the new events in real time but i did’t found any option in the document for how to handling this action

 bpy.ops.mesh.extrude_region_move

so are there any way to make something like that ?

import bpy


def my_handler(scene):
    print("new face extruded ")

bpy.app.handlers.extrude_region_move(my_handler)

The only way I know of to use handlers for running scripts in real time is with a modal operator. If you are just looking to make a slight modification to the extrude tool, I think it would be easier to convert this into a basic “run-once” operator and assign it a hotkey. The basic operator code looks something like this:

import bpy
print("
Add-on loaded.")  # debug

class MyBasicOperator(bpy.types.Operator):
    bl_idname = "object.my_basic_operator"
    bl_label = "My Basic Operator"

    def execute(self,context):
        print("Running operator.")  # debug
        print("This method is run every time the operator is launched.")  # debug
        return {'FINISHED'}

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

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

if __name__ == "__main__":
    register()

If you run that from Blender’s Python console it can be accessed from the spacebar menu by typing in “My Basic Operator”. There are more detailed examples in the templates library and the Python API docs.

thanks for your replay it’s really help full
that’s are my code now but i have a problem

i used this line to know if the extruded happen our not

    def modal(self, context, event):
        if bpy.ops.mesh.extrude_region_move != None:
            print("extruded")



        return {'PASS_THROUGH'}

but the problem is it’s run for the old extruded that’s happen before to and never stop out putting even if i stopped extruding so do you know how to fix it ?

import bpy

class ModalOperator(bpy.types.Operator):
    bl_idname = "object.modal_operator"
    bl_label = "Simple Modal Operator"

    def execute(self, context):
        print("This is the modal operator")
        return {'FINISHED'}

    def modal(self, context, event):
        if bpy.ops.mesh.extrude_region_move != None:
            print("extruded")



        return {'PASS_THROUGH'}
        

        

    def invoke(self, context, event):
        print("This is the invoker")

        context.window_manager.modal_handler_add(self)
        return {'RUNNING_MODAL'}

bpy.utils.register_class(ModalOperator)

bpy.ops.object.modal_operator('INVOKE_DEFAULT')

If an operator class contains an “invoke” method, that will be called first. Because your invoke method returns ‘RUNNING_MODAL’ Blender will look for a “modal” method in the “ModalOperator” class instead of an “execute” method. And once a ‘RUNNING_MODAL’ string is returned, Blender will keep calling the class’s modal method every time a new “event” is detected (eg: a mouse move or key press) until that modal method returns a “FINISHED” or “CANCELLED” string. I don’t think the “execute” method in your code would ever be called.

A more “standard” modal operator might look something like this:

import bpy

print("
Add-on loaded.")  # debug


class ModalOperatorTest(bpy.types.Operator):
    bl_idname = "object.modal_operator_test"
    bl_label = "My Modal Operator"

    def modal(self, context, event):
        if event.type == 'MOUSEMOVE':
            self.mouse_loc = event.mouse_region_x, event.mouse_region_y
            print(self.mouse_loc)

        elif event.type in {'LEFTMOUSE', 'MIDDLEMOUSE'}:
            return {'PASS_THROUGH'}

        elif event.type in {'ESC', 'RIGHTMOUSE'}:
            print("Add-on exited!")  # debug
            return {'CANCELLED'}

        return {'RUNNING_MODAL'}

    def invoke(self, context, event):
        context.window_manager.modal_handler_add(self)
        self.mouse_loc = event.mouse_region_x, event.mouse_region_y
        print("Add-on started!")  # debug
        return {'RUNNING_MODAL'}


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

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

if __name__ == "__main__":
    register()