Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 这是使用str.format()的可接受方式吗?_Python_Coding Style_Formatting - Fatal编程技术网

Python 这是使用str.format()的可接受方式吗?

Python 这是使用str.format()的可接受方式吗?,python,coding-style,formatting,Python,Coding Style,Formatting,我最近决定开始使用.format()而不是%(请参阅)。与{0},{1}语法不同,我想知道以下用法是否可以接受: import os def get_filename(player_name): for ext in ('jpg', 'jpeg', 'png'): filename = "data/avatars/{player_name}.{ext}".format(**locals()) if os.path.exists(filename):

我最近决定开始使用
.format()
而不是
%
(请参阅)。与
{0}
{1}
语法不同,我想知道以下用法是否可以接受:

import os
def get_filename(player_name):
    for ext in ('jpg', 'jpeg', 'png'):
        filename = "data/avatars/{player_name}.{ext}".format(**locals())
        if os.path.exists(filename):
            return filename
    return None

我喜欢它的直截了当性-局部变量进入字符串中-但我想知道是否有任何理由我不应该这样做。

局部变量()
(或
全局变量()
)传递到
格式
(或
%
)的主要问题是格式字符串通常来自不可信的源,你可能会暴露你不想暴露的变量。如果您只是格式化一个文本字符串,这不是问题,但是如果您可能有不受信任的格式字符串,那么您必须非常仔细地考虑您正在做什么,而不这样做更容易

更次要的问题是,一些代码的读者不理解
本地人
,或者
**
语法,并且很难弄清楚它是做什么或为什么工作的。这不是什么争论。事实上,你甚至可以说,Python的许多设计决策都归结为确保这几乎从来都不是一个好的论据——该语言足够大,可以合理地期望读者理解/学习你编写的任何Python语言。但这仍然值得思考

然后是风格问题。每隔几个月,就会有人建议使用这种语言应该更容易做到这一点,并在邮件列表上引发争论。有些人肯定认为这感觉是“含蓄的,而不是明确的”。其他人不同意。我认为这里的魔法局部变量不会是pythonic,这已经很确定了……但是如果你必须显式地传递
局部变量()
,也许这是好的,也许不是。像大多数没有达成共识的风格争论一样,这真的取决于你。(顺便说一句,
格式
API最终来自这样一个参数,最初的建议是使用隐式的
局部变量
进行更类似perl的字符串插值)

但最终,你必须考虑你在储蓄什么。比较一下:

filename = "data/avatars/{player_name}.{ext}".format(**locals())
致:


您的版本并不更清晰、更明确、更易于键入,甚至更短。因此,我想说,如果没有好处,那么让新手阅读起来有点困难的风险,以及让社区的某些部分感到恼火的风险(即使是出于不好的原因),是不值得的。

正如我上面所评论的,这不应该用于不可信的来源。而且,它可能不够明确,不足以成为蟒蛇

也可以定义一个函数来实现这一点,但要访问正确的局部变量,它需要进行一些帧处理

def format_locals(string):
    return string.format(**sys._getframe().f_back.f_locals)
这种模式不好,Pypy之类的东西无法选择这种代码

我将使用以下代码(除非您需要Python 2.6支持,因此必须添加索引):


如果字符串来自不受信任的来源,则可能不希望公开变量。但是,按现在的方式,没有问题。如果你曾经,甚至可能,将格式化由不可信来源提交的字符串,你肯定不想这样做。除此之外,一些pythonistas不喜欢这是“含蓄的而不是明确的”——每当有人建议语言应该让这更容易/更明显,但其他人不同意时,邮件列表上就会有争论,所以我想说,这是一个风格问题,尚未解决。我同意让当地人接触潜在的不可信来源的观点。也就是说,我个人认为在这种风格中使用
**
没有问题。这可能会混淆一些处理python代码的工具,例如,变量
ext
之类的虚假警告在此函数中未被使用。这与
%
没有什么区别。关于让局部变量更容易或更难神奇地
%
-格式化的争论变成了关于让局部变量更容易或更难神奇地
{}
-格式化的争论,除了语法之外,参数没有任何变化。有人可能会说,对于一个包含大量占位符的长格式字符串,很难跟踪哪个占位符是哪个参数(必须计数),对于像
“{player\u name}”这样的显式关键字参数。format(player\u name=player\u name)
有一些难闻的三重复制。@PavelAnossov:是的,这是我的主要问题。我喜欢使用显式格式字符串,但是
.format
的参数并不漂亮,除非我使用
**locals()
,这可以说是hack-y。不过,我认为abarnert是对的,在这种特殊情况下,它们都具有同等的可读性,如果不是后者更清晰的话。老实说,我还没有遇到过跟踪格式字符有困难的情况。@PavelAnossov:True。然后,您可能会再次争辩说,一个包含大量占位符的长格式字符串应该使用比
格式
更复杂的模板。如果您正在做太常见的“现在为我们构建它,以后再弄清楚如何国际化”的事情,您可能会想为2.7/3.x添加索引。
def format_locals(string):
    return string.format(**sys._getframe().f_back.f_locals)
filename = 'data/avatars/{}.{}'.format(player_name, ext)