Could you run some parts in the script of blender
The thing you described sounds like a cell running script system: Running part of python script - Stack Overflow
Which could found in Spyder and IPython(Jupyter) as IDE level. Blender itself doesn't support this feature for now since it's a little bit complicate. Although  you can simply define block using tag or selection code to specified some code from text editor and exec it. Which is described in Blender Tips and Tricks — Blender Python API.
Below is a simple add on (operator) which will find the first match # region # endregion block before current line and run the cell.


I do update a newer version in Github.
import bpy

_START_TAG = '# region'
_END_TAG = '# endregion'


class TEXT_OT_run_cell_script(bpy.types.Operator):
    &quot;&quot;&quot;Run current selected cell script in python.&quot;&quot;&quot;
    bl_idname = &quot;text.runcell&quot;
    bl_label = &quot;Run current cell&quot;

    @classmethod
    def poll(cls, context):
        return context.area.type == 'TEXT_EDITOR'

    @staticmethod
    def get_codecells_mapping(c_lines: list) -&gt; dict:
        stack = []
        cells = {}
        for idx, line in enumerate(c_lines):
            if line.startswith(_START_TAG):
                stack.append((line[len(_START_TAG) :], idx))
            elif line.startswith(_END_TAG):
                if len(stack) == 0:
                    continue
                cell_name, idx_start = stack.pop()
                cells[idx_start] = (cell_name, idx_start, idx)
        for cell_name, idx_start in stack:
            # Fill unmatched block
            cells[idx_start] = (cell_name, idx_start, len(c_lines) - 1)
        return cells

    def execute(self, context):
        # print('EXECUTE addon')
        text_obj = context.area.spaces.active.text
        codes = text_obj.as_string()
        # print(codes)
        c_lines = codes.split('\n')
        cells = self.get_codecells_mapping(c_lines)
        # print(cells)
        if cells:
            cell_idx = -1
            idx = text_obj.current_line_index
            for i in range(idx, -1, -1):
                if c_lines[i].startswith(_START_TAG):
                    cell_idx = i
                    break
            name, start, end = cells.get(
                cell_idx,
                (text_obj.name, 0, len(c_lines) - 1)
            )
            # print((name, start, end))
            self.report({'INFO'}, f&quot;Execute cell: [{name}]({start}:{end})&quot;)
            exec(
                compile(
                    '\n'.join(c_lines[start:end]),
                    filename=f&quot;S-Cell-{name}&quot;,
                    mode='exec',
                )
            )
        return {'FINISHED'}


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


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

if __name__ == &quot;__name__&quot;:
    register()

Text block:
# region Hello
a = &quot;Hello world&quot;
# endregion

# region print
print(a)
# endregion

# region import BPY
import bpy
# endregion

# region move obj
bpy.context.object.location.x += 0.1
# endregion


New Information
This addon manually provide a local scope to the exec function, and that local is stored in module, which give it the ability to share variable among each cell. But the global variable is ignore and pass as an empty dictionary. It might cause some strange behavior (I mean, crash) when cell code itself accessing these built in function.
Old Information
Notice that since we don't pass any local inside the execute function. These cells will use the scope that inside the operator. It will make it hard to use since the scope is not provide by user and script cells variable are not share among each other.