> U plně volitelných parametrů se mnohdy jako výchozí hodnota používá None, což má ovšem jednu nevýhodu – tímto způsobem totiž nelze odlišit explicitní předání None (to je totiž mnohdy zcela validní hodnota) od neuvedení parametru.
Setkal se s tím někdo v praxi? Pokud se pamatuju, řešil jsem rozlišování None ve smyslu žádosti o výchozí hodnotu vs None jako hodnotu samu o sobě jenom jednou, a to jsem páchal zotavující se čtení ze sekvence slovníků. Ale tam by mi výpustek sám o sobě nepomohl, když může None znamenat hodnotu, tak i Ellipsis... Přijde mi hezčí vyrobit si vlastní sentinel.
_sentinel = object()
def get_first_existing_value(key:str, *objs: dict[str,T], default:T|Literal[_sentinel] = _sentinel) -> T:
for o in objs:
try:
return o[key]
except KeyError:
pass
if default is _sentinel:
raise KeyError(key)
return default
PS: díky za ten příklad, kde se zapisuje do Ellipsis. Tohle mě zatím nenapadlo. Jen nevím, jestli to vypovídá spíš o zvyšující se příčetnosti nebo klesající zvědavosti.
Python není Lua, všechno, co potřebovalo referenci na object už ji dostalo a drží si ji hodnotou. Dají se dělat i nové třídy - samozřejmě pokud ve stylu py2 nedědí object - a jejich MRO končí skutečným objectem. Tyhle kousky jazyka budou chodit přes C API a ukecat garbage collector se mi nepodařilo.
>>> actual_object, object=object, None
>>> class Foo:
... def __init__(self):
... print("Init foo")
...
>>> Foo.__mro__
(<class '__main__.Foo'>, <class 'object'>)
>>> Foo.__mro__[-1] is actual_object
True
>>> f = Foo()
Init foo