the Session uses the method session._is_clean() internally to check if going through the flush() steps is warranted, which is roughly equivalent to the check you're doing, though it is doing less work to make this decision - if you take a look at what it does, compared to the implementation for .new, .dirty, .deleted, you save on the iteration of those collections and the translation of all the InstanceState objects into userland objects.
There's another caveat, which is that even if _is_clean() is false, that's not a total guarantee that SQL will be emitted on flush. If you changed one object attribute to be the same value that it already was, for example, that's a "dirty" event, but when the flush runs through, it will see no net change and not emit an UPDATE.
This is part of the reason _is_clean() at the moment still has an underscore. Easier to keep the underscore than to promise a completely predictable usage pattern :).