Yep. Debuggers are more powerful, they can do everything `printf` debugging can do + more, but take more work to set up. For interpreted languages, they often take more work to use than just adding a print statement & rerunning, for compiled languages the reverse is more likely.
Conditional breakpoints that run a script and continue can be used equivalently to printf debugging, just set it to print when the selected line is hit. You can do this without restarting the application, even for multithreaded code.
Also watchpoints, for the equivalent but at a memory location instead of a code line.
Nothing to be ashamed of, imo; printf debugging works incredibly well!