I often do the same myself for the managers parts of an app which, in theory, could be reduced to simple, very sequential, functional programming.
The main advantage to it (for me) is that it encapsulates well your main loop or your run-once execution, and it allows to configure that run and persist data efficiently and cleanly across blocks, fundamentally re-configuring it as needed without having to change the code itself. Not to mention the ability to subclass an execution to a different and extended one.
It also tends to be a lot easier to expand the main that way, then it is when you have a solid block of 200 lines throwing around rather cryptically scoped stuff.
The self, after you write enough Python, kinda goes away as an impedement, and personally I like how it immediately offers a visual distinction between what I will obviously want to persist across scopes, and what is a disposable element that I DO want to run out of scope and get collected as soon as a particular step is done.
Last but not least, some people will object orient anything they get their hands on, or won't be able to read it. I'm one of them :)