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 likein
andnot 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
.value
or.name
at 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.
...