Is a string formatter that pulls variables from its calling scope bad practice?

后端 未结 4 1596
北恋
北恋 2020-11-30 14:04

I have some code that does an awful lot of string formatting, Often, I end up with code along the lines of:

\"...\".format(x=x, y=y, z=z, foo=foo, ...)
         


        
4条回答
  •  天涯浪人
    2020-11-30 14:27

    Update: Python 3.6 has this feature (a more powerful variant) builtin:

    x, y, z = range(3)
    print(f"{x} {y + z}")
    # -> 0 3
    

    See PEP 0498 -- Literal String Interpolation


    It[manual solution] leads to somewhat surprising behaviour with nested functions:

    from callerscope import format
    
    def outer():
        def inner():
            nonlocal a
            try:
                print(format("{a} {b}"))
            except KeyError as e:
                assert e.args[0] == 'b'
            else:
                assert 0
    
        def inner_read_b():
            nonlocal a
            print(b) # read `b` from outer()
            try:
                print(format("{a} {b}"))
            except KeyError as e:
                assert 0
        a, b = "ab"
        inner()
        inner_read_b()
    

    Note: the same call succeeds or fails depending on whether a variable is mentioned somewhere above or below it.

    Where callerscope is:

    import inspect
    from collections import ChainMap
    from string import Formatter
    
    def format(format_string, *args, _format=Formatter().vformat, **kwargs):
        caller_locals = inspect.currentframe().f_back.f_locals
        return _format(format_string, args, ChainMap(kwargs, caller_locals))
    

提交回复
热议问题