You can use the arcpy.sa.Raster class, which has a built-in raster cell iterator:
def get_raster_areas(raster_path, upper_bounds):
"""Returns the areas of a raster that are below the given values.
raster_path: str, path to the raster
upper_bounds: [float], the upper bounds of your desired value bins
"""
# get raster object
raster = arcpy.sa.Raster(raster_path)
# get cell area
dimensions = raster.getRasterInfo().getCellSize()
cell_area = dimensions[0] * dimensions[1]
# initialize the area list
upper_bounds.sort() # it's important that upper_bounds is sorted
areas = [0 for x in upper_bounds]
# loop over the raster cells
for row, col in raster:
# loop over the upper_bounds
for i, ub in enumerate(upper_bounds):
# if raster cell value is below upper bound,
# add cell_area to the corresponding element in the areas list
# and break, so this cell doesn't also get added to the other (higher) bins
# (that's why we needed to make sure upper_bounds is sorted)
if raster[row, col] < ub:
areas[i] += cell_area
break
# return the area list
return areas
rp = r"G:\...\DGM1_2017_HB1.TIF" # 100x100m raster of elevations in a coastal town
bins = [0, 8, 12, 15]
areas = get_raster_areas(rp, bins)
for b in range(len(bins)):
print(f"elevation < {bins[b]}m: {areas[b]}m²")
#elevation < 0m: 33.0m² # below 0m
#elevation < 8m: 997968.0m² # between 0m and 8m
#elevation < 12m: 0m² # between 8m and 12m
#elevation < 15m: 0m² # between 12m and 15m
Have a great day!
Johannes