Python has an odd tolerance for try - except controlling the flow. They have also an ancronym to justify it: EAFP, which is Easier to ask for forgiveness than permission.
Just to remember that OOP does not fit all. Cited from this document, emphases added by me.
Ada 83 was object-based, allowing the partitioning of a system into modules corresponding to abstract data types or abstract objects. Full OOP support was not provided since, first, it seemed not to be required in the real time domain that was Ada's primary target, and, second, the apparent need for automatic garbage collection in an OO language would have interfered with predictable and efficient performance.
You can argue that C++ hasn't automatic garbage collection, hence the second point doesn't seem a good reason at all. I think there were other concerns too, e.g., more requirements about “safety”.
However, large real time systems often have components such as GUIs that do not have real time constraints and that could be most effectively developed using OOP features. In part for this reason, Ada 95 supplies comprehensive support for OOP, through its “tagged type” facility: classes, polymorphism, inheritance, and dynamic binding. Ada 95 does not require automatic garbage collection but rather supplies definitional features allowing the developer to supply type specific storage reclamation operations (“finalization”). Ada 2005 provided additional OOP features including Java-like interfaces and traditional operation invocation notation.
Ada is methologically neutral and does not impose a “distributed overhead” for OOP. If an application does not need OOP, then the OOP features do not have to be used, and there is no run-time penalty.