关于使用以下模式是否有任何缺点,警告或不良做法警告?
def buildString(user, name = 'john', age=22):
userId = user.getUserId()
return "Name: {name}, age: {age}, userid:{userId}".format(**locals())
Run Code Online (Sandbox Code Playgroud)
我有一个非常重复的字符串生成代码来编写并且很想使用它,但是关于使用的东西locals()让我感到不舒服.这有意外行为的危险吗?
编辑:上下文
我发现自己经常写下这样的东西:
"{name} {age} {userId} {etc}...".format(name=name, age=age, userId=userId, etc=etc)
Run Code Online (Sandbox Code Playgroud) 这是一个龙卷风模板(例如,在文件logout.html中)我在注销过程中的错误渲染:
{% if logout_error %}
Oops! The logout failed. Please close all open documents and try again
{% end %}
Run Code Online (Sandbox Code Playgroud)
这可以使用
self.render("logout.html", logout_error=True)
Run Code Online (Sandbox Code Playgroud)
如果注销成功,我必须这样做
self.render("logout.html", logout_error=False)
Run Code Online (Sandbox Code Playgroud)
如果我忽略了logout_error=False,我明白了
NameError: global name 'logout_error' is not defined
Run Code Online (Sandbox Code Playgroud)
如果有很多标志(都是假的),关键字参数可能会堆积起来.有没有一种方法我可以问模板考虑logout_error的False,如果它不存在?
我通常使用以下模式(如本问题中所述):
a=1
s= "{a}".format(**locals())
Run Code Online (Sandbox Code Playgroud)
我认为这是编写易读代码的好方法.
有时,"链接"字符串格式是有用的,以便"模块化"复杂字符串的创建:
a="1"
b="2"
c="{a}+{b}".format(**locals())
d="{c} is a sum".format(**locals())
#d=="1+2 is a sum"
Run Code Online (Sandbox Code Playgroud)
很快,代码就被纠缠不清了X.format(**locals()).为了解决这个问题,我尝试创建一个lambda:
f= lambda x: x.format(**locals())
a="1"
b="2"
c= f("{a}+{b}")
d= f("{c} is a sum")
Run Code Online (Sandbox Code Playgroud)
但这引发了一个KeyError,因为locals()是lambda的本地人.
我还尝试仅在最后一个字符串上应用格式:
a="1"
b="2"
c="{a}+{b}"
d="{c} is a sum".format(**locals())
#d=="{a}+{b} is a sum"
Run Code Online (Sandbox Code Playgroud)
但这不起作用,因为python只格式化一次.现在,我可以编写一个重复格式化的函数,直到没有其他事情要做:
def my_format( string, vars ):
f= string.format(**vars)
return f if f==string else my_format(f, vars)
Run Code Online (Sandbox Code Playgroud)
但我想知道:有更好的方法吗?
最近有人告诉我,我们可以在Python中打印变量,就像Perl一样.
代替:
print("%s, %s, %s" % (foo, bar, baz))
Run Code Online (Sandbox Code Playgroud)
我们可以这样做:
print("%(foo)s, %(bar)s, %(baz)s" % locals())
Run Code Online (Sandbox Code Playgroud)
像在Perl中那样,在Python中打印变量的方式是不是很简单?我认为第二个解决方案实际上看起来非常好并且使代码更具可读性,但是那里的locals()让它看起来像是一种令人费解的方式.
这不是一个重复的,因为这对于使用较新的str.format(),上面的链接的问题也越低质量的,而且我认为这个问题是十分不同来证明它的经典性.
问题:
有人可能会在这里遇到错误,但我们可以为str.format方法提供未使用的关键字参数.
>>> '{a}{b}'.format(a='foo', b='bar', c='baz')
'foobar'
Run Code Online (Sandbox Code Playgroud)
这使代码如下:
>>> foo = 'bar'
>>> baz = 'fizzbuzz'
>>> '{foo}{baz}'.format(**locals())
'barfizzbuzz'
>>> baz = datetime.datetime.now()
>>> '{foo}_{baz}'.format(**locals())
'bar_2013-12-20 18:36:55.624000'
Run Code Online (Sandbox Code Playgroud)
这是一个很好的做法,在一个函数的闭包内做?
def make_foo_time_string():
foo = 'bar'
baz = datetime.datetime.now()
return '{foo}{baz}'.format(**locals())
Run Code Online (Sandbox Code Playgroud)
可能的缺点是什么?使用额外周期加载的额外变量?这是方便吗?我不记得看到这个用得多,它会被认为是Python的惯用语吗?
更新我发现使用旧样式字符串插值的规范建议用法:https://wiki.python.org/moin/PythonSpeed/PerformanceTips 尽管如此,它似乎是一个相当古老的文档.
"更好的是,为了便于阅读(除了作为程序员之外,这与效率无关),使用字典替换:"
out = "<html>%(head)s%(prologue)s%(query)s%(tail)s</html>" % locals()
Run Code Online (Sandbox Code Playgroud) 如果我将Python函数定义为f(a, b, c),是否有一种直接的方法来获取将正式名称映射到传入的值的字典?也就是说,从内部来看f,我希望能够获得一个字典{'a': 1, 'b': 2, 'c': 3}来接听电话f(1, 2, 3).
我想这样做,所以我可以直接在字符串替换中使用参数和值,例如"%(a)s %(b)s %(c)s" % d.我可以做类似的事情d = dict(a=a, b=b, c=c),但如果可能的话,我宁愿避免重复.
我知道通过定义fas 很容易做到这一点f(**kwds),但这也使得函数所期望的参数变得不那么明显.看起来可能有一些方法可以通过inspect模块实现这一点,但它可能太复杂而不值得.
我怀疑这个问题并没有给出好的答案,但我很高兴被证明是错的.实现上述目标的替代方法也是受欢迎的.
这是一些代码:
foo = "Bears"
"Lions, Tigers and %(foo)s" % locals()
Run Code Online (Sandbox Code Playgroud)
我的PEP8 linter(SublimeLinter)抱怨这个,因为foo是"未引用的".我的问题是PEP8是否应该将这种类型的字符串插值计为"引用",或者是否有充分的理由考虑这种"坏的风格".
python ×7
string ×2
formatting ×1
lambda ×1
locals ×1
parameters ×1
pep8 ×1
scope ×1
tornado ×1