Hacker News new | past | comments | ask | show | jobs | submit login

    >>> 'User {user} has logged in and did an action {action}.'.format(**locals())

To me, this is pretty gross. This implicitly requires all the correct variables to be bound in the local scope, and there's no easy way to check that this is the case without reading all of the code leading up to this point (which is bad, in my opinion). Because what this really does is create string-level variables `user` and `action` and pass the values of similarly-named (i.e., shadowed) variables in the outer (but still local) scope in their place. This is why IDEs struggle with this: they can't simply know the contents of the dictionary returned by the function `locals()` without actually executing the code (unless they special-case calls to functions named `locals`, but this causes problems if the user ever shadows this name).

F-strings directly use the bound variables in the outer (but still local) scope:

    >>> f'User {user} has logged in and did an action {action}.'
    'User Jane Done has logged in and did an action buy.'
This avoids the shadowing problem, thus making it easy to use with IDEs and (IMO) easier to grok while reading directly, although maybe most people don't think about shadowing to the same extent I do and wouldn't be as bothered by this in general. Still, the IDE support is incredibly useful.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact