On Sun, Dec 5, 2021 at 5:29 AM Barry Scott <barry@barrys-emacs.org> wrote:
On 1 Dec 2021, at 06:16, Chris Angelico <rosuav@gmail.com> wrote:
I've just updated PEP 671 https://www.python.org/dev/peps/pep-0671/ with some additional information about the reference implementation, and some clarifications elsewhere.
(I suspect that there was a reply that I should be replying to but, cannot find one appropriate)
I have a lot of code that exploits the fact that passing an explicit None will cause the early bound default idiom to set the default for me.
def inner(timestamp=None): if timestamp is None: timestamp = time.time() do_stuff...
def outer(timestamp=None): inner(timestamp=timestamp)
outer can in an idiomatic way have inner default timestamp and not have to know what that means.
If you need outer() to be able to have a value that means "use the default", then there are three options: 1) Don't pass timestamp at all. In simple cases where it will only and always specify the default, this is fine. 2) Define a sentinel that is indeed part of your API. 3) Use *args or **kwargs to choose whether to pass it or not (best if there are multiple of them). You can continue to use the existing system of "if none, do this", or you can flip it around and have the sentinel as a special token within your code: def inner(timestamp=>time.time()): if timestamp is None: timestamp = time.time() Depends on how important this feature is outside of your own helper functions. (I would probably not do this for None specifically - if it's purely internal, I'm more likely to use a dedicated local sentinel object.) But as soon as there are two or three arguments that "might have to be passed, might not", it's far more readable to use kwargs to pass just the ones you want. def outer(**kwargs): inner(**kwargs) That way, if something changes in inner(), you don't have to worry about breaking your caller's API.
With late bound I cannot do this without more complex pattern of building an arg list.
What if passing None still worked? I know the argument that there are more sentinels then None.
def inner(timestamp=>time.time()) do_stuff...
def outer(timestamp=None): inner(timestamp=timestamp)
The code in inner that decides to when to allow the default could check for timestamp being missing or arg present and None.
Would the lack of support for other sentinels out weight the simple way to get the default applied?
None is most assuredly not going to trigger a late-bound default. Python is not JavaScript :) ChrisA