Python Language =============== Types ----- Singleton Objects ***************** * ``Ellipsis`` or ``...`` literals * ``NotImplemented`` object * ``None`` The ``Ellipsis`` object's meaning is up to the API that uses it, here are two common ones. .. code-block:: python from typing import Tuple, Callable a = ... b = Ellipsis print(a is b) # True # Arbitrary-length homogeneous tuples can be expressed # using one type and ellipsis, for example t = Tuple[int, ...] def partial(func: Callable[..., str], *args) -> Callable[..., str]: """ It is possible to declare the return type of a callable without specifying the call signature by substituting a literal ellipsis (three dots) for the list of arguments """ ... # Ellipsis is also expression and a statement The ``NotImplemented`` Object is another singleton that is returned from comparisons and binary operations when they are asked to operate on types they don’t support. It is not an Exception The Null Type, ``None`` is a singleton object. For these three singleton objects, identity check should be used with ``is`` and ``is not`` .. code-block:: python a = None b = None print(a is b) Loops and iterators ------------------- The ``for else`` construct. The ``else`` clause only executed upon full and successful completion of the iteration without premature breaking or Exception raised .. code-block:: python for x in range(5): print(x) if x == 5: break else: continue else: print('done!') The ``while else`` construct, The else block works similarly to the ``for else`` construct .. code-block:: python c = 0 while c < 3: print(c) c += 1 else: print('complete!') Try Clause ---------- For catching generic or specific exceptions, and for proper resource cleanup and finalization. The first example should print 1 3 4, and the second should print 2 4 .. code-block:: python try: print("1") except RuntimeError as ex: print("2") else: print("3") finally: print("4") try: raise RuntimeError() print("1") except RuntimeError as ex: print("2") else: print("3") finally: print("4") Scope ----- global and nonlocal ******************** .. code-block:: python # global scope a = 1 b = 1 def work(): a = 5 global b b = 5 print(a, b) .. code-block:: python def work(): x = 1 # local scope y = 1 def other_work(): x = 2 # local scope nonlocal y y = 2 other_work() print(x, y) work() Function Definition ------------------- Function parameters https://docs.python.org/3/tutorial/controlflow.html#function-examples .. code-block:: python def standard_arg(arg): print(arg) def pos_only_arg(arg, /): print(arg) def kwd_only_arg(*, arg): print(arg) def combined_example(pos_only, /, standard, *, kwd_only): print(pos_only, standard, kwd_only) Datetime -------- Formatting and Parsing docs: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes Construction and TZ Conversions ******************************* .. code-block:: python import datetime as dtx from zoneinfo import ZoneInfo tz_utc = ZoneInfo('UTC') tz_est = ZoneInfo('US/Eastern') tz_local = ZoneInfo('localtime') # best to always make it timezone aware dt1 = dtx.datetime(2019, 11, 12, 14, 30, 20, tzinfo=tz_utc) # timezone conversion dt2 = dt1.astimezone(tz_est) print(dt1) print(dt2) print("daylight saving offset: ", dt2.dst()) dt3 = dtx.datetime(2019, 7, 12, 14, 30, 20, tzinfo=tz_utc) dt4 = dt3.astimezone(tz_est) print(dt3) print(dt4) print("daylight saving offset: ", dt4.dst()) # This adjusts for daylight saving dt5 = dt4.replace(month=12) print(dt5) # This also adjusts for daylight saving dt6 = dt4 + dtx.timedelta(weeks=22, days=-1) print(dt6) Timezones and Timestamps ************************ .. code-block:: python import datetime as dtx from datetime import timezone from zoneinfo import ZoneInfo from time import time # localtime, naive, which should be okay to use in most instances now_x = dtx.datetime.now() # utc, naive, and very dangerous to use, since it might be assumed to be localtime # AVOID THIS AT ALL COST now_y = dtx.datetime.utcnow() # hour offset is correct, but is not daylight saving aware now1 = dtx.datetime.now(dtx.timezone(dtx.timedelta(hours=-5))) # tz aware utc datetime. These two are equivalent now2 = dtx.datetime.now(timezone.utc) now2_x = dtx.datetime.now(ZoneInfo("UTC")) # localtime, tz aware and daylight saving aware now3 = dtx.datetime.now(ZoneInfo("localtime")) # To get the UNIX UTC Epoch in millis, all of the above will work EXCEPT now_y will be incorrect millis_a = round(now3.astimezone(tz=timezone.utc).timestamp() * 1000) # Here to confirm that the calculation was correct millis_b = round(time() * 1000) # To restore a datetime from Epoch Millis dtx.fromtimestamp(millis_a / 1000.0, tz=ZoneInfo("UTC")) Time deltas *********** .. code-block:: python import datetime as dtx dt1 = dtx.datetime.now() # deltas can be negative dt2 = dt1 + dtx.timedelta(hours=-4, minutes=-20, seconds=-10) # order matters when calculation timedeltas print((dt1 - dt2).total_seconds()) print((dt2 - dt1).total_seconds()) delta = dt1 - dt2 # total seconds delta is the default print("total seconds diff: ", delta.total_seconds()) # but other units can be calculated by dividing the delta by 1 of that unit print("total hours diff: ", delta / dtx.timedelta(hours=1)) print("total days diff: ", delta / dtx.timedelta(days=1)) print("total minutes diff: ", delta / dtx.timedelta(minutes=1)) print("hours in a week", dtx.timedelta(weeks=1) / dtx.timedelta(hours=1)) # deltas can be fractional dt3 = dt1 + dtx.timedelta(hours=3.5) print(dt1) print(dt3)