我正在开发一个应用程序,我在其中执行一些请求以获取对象ID。在每一个之后,我调用一个方法(get_actor_info()
)将此id作为参数传递(参见下面的代码)。
ACTOR_CACHE_KEY_PREFIX = 'actor_'
def get_actor_info(actor_id):
cache_key = ACTOR_CACHE_KEY_PREFIX + str(actor_id)
可以注意到,我正在将actor_id
转换为string
并将其与前缀连接起来。但是,我知道我可以通过多种其他方式(例如.format()
或'%s%d'
)来实现这一点,这导致了我的问题:在可读性方面,'%s%d'
会比字符串连接更好吗? ,代码约定和效率?
由于
答案 0 :(得分:11)
这很容易成为一个基于意见的线程,但我发现格式化在大多数情况下更具可读性,并且更易于维护。在不进行“精神连接”的情况下,更容易想象最终字符串的外观。例如,哪些更具可读性?
errorString = "Exception occurred ({}) while executing '{}': {}".format(
e.__class__.__name__, task.name, str(e)
)
或者:
errorString = "Exception occurred (" + e.__class__.__name__
+ ") while executing '" + task.name + "': " + str(e)
至于是否使用%
或.format()
,我可以更客观地回答:使用.format()
。 %
是“旧式”,根据Python Documentation,它们很快就会被移除:
由于
str.format()
很新,很多Python代码仍使用%
运算符。但是,由于最终将从语言中删除这种旧格式,因此通常应使用str.format()
。
文档的后续版本已经停止提及这一点,但尽管如此,.format()
是未来的方式;用它!
连接速度更快,但这不应该是一个问题。使您的代码可读和可维护作为第一线目标,然后优化您稍后需要优化的部分。过早优化是万恶之源;)
答案 1 :(得分:5)
在性能方面,连接更好。在您的示例中,连接和替换都是可读的,但是当涉及到更复杂的模板时,替换会赢得简单性和可读性竞争。
例如,如果您有数据并且想要在html中显示它,则连接会让您头疼,而替换将简单易读。
答案 2 :(得分:3)
Python 3.6将引入另一个选项:
ACTOR_CACHE_KEY_PREFIX = 'actor_'
def get_actor_info(actor_id):
cache_key = f'{ACTOR_CACHE_KEY_PREFIX}{actor_id}'
效果应该与'{}{}'.format(ACTOR_CACHE_KEY_PREFIX, actor_id)
相当,但可以说更具可读性。
答案 3 :(得分:0)
我猜想,如果要连接的所有术语都是常量,则可以通过python优化与+
运算符的连接以提高性能。例如:
DB_PREFIX = 'prod_'
INDEX_PREFIX = 'index_'
CRM_IDX_PREFIX = DB_PREFIX + INDEX_PREFIX + 'crm_'
但是大多数情况下,格式函数和运算符用于连接变量内容。例如:
crm_index_name = "{}_{}".format(CRM_IDX_PREFIX, index_id)
实际上,如果您使用+
运算符进行连接,如下所示:
crm_index_name = CRM_IDX_PREFIX + '_' + str(index_id)
您正在通过自定义代码以固定方式定义格式。如果您使用带有命名引用的格式字符串,则代码更具可读性。例如:
crm_index_name = "{db_prefix}_{idx_prefix}_{mod_prefix}_{id}".format(
db_prefix=CRM_IDX_PREFIX,
idx_prefix=INDEX_PREFIX,
mod_prefix='crm',
id=index_id,
)
这样,您就可以将格式定义为常量。例如:
IDX_FORMAT = "{db_prefix}_{idx_prefix}_{mod_prefix}_{id}"
crm_index_name = IDX_FORMAT.format(
db_prefix=CRM_IDX_PREFIX,
idx_prefix=INDEX_PREFIX,
mod_prefix='crm',
id=index_id,
)
如果将来需要更改格式,此结果将更加清楚。 例如,要更改分隔符的顺序,您只需更改 将字符串格式化为:
IDX_FORMAT = "{db_prefix}_{mod_prefix}_{idx_prefix}-{id}"
此外,为了进行调试,您可以将所有这些变量分配给字典,并将其作为关键字参数传递给format函数:
idx_name_parts = {
'db_prefix': CRM_IDX_PREFIX,
'idx_prefix': INDEX_PREFIX,
'mod_prefix': 'crm',
'id': index_id,
}
crm_index_name = IDX_FORMAT.format(**idx_name_parts)
利用globals()函数,我们还可以:
IDX_FORMAT = "{CRM_IDX_PREFIX}_{mod_prefix}_{INDEX_PREFIX}-{index_id}"
crm_index_name = IDX_FORMAT.format(mod_prefix = 'crm', **globals())
这类似于python3的formatted string literal:
crm_index_name = f"{CRM_IDX_PREFIX}_crm_{INDEX_PREFIX}-{index_id}"
我还将 Internationalization 视为另一个使用上下文,其中格式化表达式比+
运算符更有用。输入以下代码:
message = "The account " + str(account_number) + " doesn't exist"
如果您将gettext module之类的翻译功能与+
运算符一起使用,它将是:
message = _("The account ") + str(account_number) + _(" doesn't exist")
因此最好翻译整个格式的字符串:
message = _("The account {account_number} doesn't exist").format(account_number)
以便完整的消息在西班牙语翻译文件中更具意义:
#: main.py:523
msgid "The account {account_number} doesn't exist"
msgstr "La cuenta {account_number} no existe."
这对于将自然语言的语法强加改变的自然语言翻译特别有用,例如 german 语言。