I absolutely love using operator overrides in low-level objects because it can make the caller's use case WAY more intuitive. There are certainly some pitfalls though.
- If you're overriding
__getitem__and__setitem__to make an object more dictionary-like, make sure to also override__iter__OR__contains__since they're called to handle membership tests likeinandnot in. (ref: https://docs.python.org/3/reference/expressions.html#membership-test-operations)
Enums can be a little tedious in Python, but there are a few things I try to do to streamline usage:
- Never build lists or structures that contain the Enum entry names or values, unless some level of serialization is being done. Always use Enum instances themselves.
- Only use
.valueor.nameat the very lowest level of your code, and only if necessary. Most comparisons, set operations, and looping can be done with the Enum instances directly.
For long running tasks or functions in Python, it's sometimes helpful to use a while True loop in concert with a generalized except Exception handler. This will generally work fine, but remember to exclude exceptions that truly should be raised, such as KeyboardInterrupt and CancelledError (in the case of code run within an async task/co-routine).
Before:
while True:
try:
# Do some stuff
...
except Exception as ex:
# Bad stuff happened, handle it however you need to.
...
After:
while True:
try:
# Do some stuff
...
except asyncio.CancelledError:
# This task has been cancelled.
raise
except Exception as ex:
# Bad stuff happened, handle it however you need to.
...