Python Language
Types
Singleton Objects
Ellipsisor...literalsNotImplementedobjectNone
The Ellipsis object’s meaning is up to the API that uses it, here are two common ones.
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
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
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
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
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
# global scope
a = 1
b = 1
def work():
a = 5
global b
b = 5
print(a, b)
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
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
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
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
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)