Python string formatting: % vs concatenation

前端 未结 4 1000
不思量自难忘°
不思量自难忘° 2020-12-09 12:05

I\'m developing an application in which I perform some requests to get an object id. After each one of them, I call a method (get_actor_info()) passing this id

4条回答
  •  盖世英雄少女心
    2020-12-09 12:57

    I guess that, if all the terms to concatenate are constants, the concatenation with the + operator might be optimized by python for performance. Ex.:

    DB_PREFIX = 'prod_'
    INDEX_PREFIX = 'index_'
    
    CRM_IDX_PREFIX = DB_PREFIX + INDEX_PREFIX + 'crm_'
    

    But most of the cases the format function and operators are used to concatenate with variable content. E.g:

    crm_index_name = "{}_{}".format(CRM_IDX_PREFIX, index_id)
    

    In practical terms, if you use the + operator to concatenate like this:

    crm_index_name = CRM_IDX_PREFIX + '_' + str(index_id)
    

    you are defining the format by custom code in a fixed way. If you use a format string with named references the code is more readable. E.g:

    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,
    )
    

    That way you have the advantage to define the format as a constant. E.g:

    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,
    )
    

    And this result more clear in case that you need to change the format in the future. For example, in order to change the order of the separators you only need change the format string to:

    IDX_FORMAT = "{db_prefix}_{mod_prefix}_{idx_prefix}-{id}"
    

    As a plus, in order to debug you can assign all those variables to a dictionary and pass it as keyword parameters to the format function:

    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)
    

    Taking advantage of the globals() function we can also:

    IDX_FORMAT = "{CRM_IDX_PREFIX}_{mod_prefix}_{INDEX_PREFIX}-{index_id}"
    
    crm_index_name = IDX_FORMAT.format(mod_prefix = 'crm', **globals())
    

    That is similar to the python3's formatted string literal:

    crm_index_name = f"{CRM_IDX_PREFIX}_crm_{INDEX_PREFIX}-{index_id}"
    

    I also see Internationalization as another use context where formatted expressions are more useful that + operator. Take the following code:

    message = "The account " + str(account_number) + " doesn't exist"
    

    if you use a translation feature like the gettext module with the + operator it would be:

    message = _("The account ") + str(account_number) + _(" doesn't exist")
    

    so it is better to translate the whole format string:

    message = _("The account {account_number} doesn't exist").format(account_number)
    

    so that the complete message has more sense in the spanish translation file:

    #: main.py:523
    msgid "The account {account_number} doesn't exist"
    msgstr "La cuenta {account_number} no existe."
    

    That is specially helpful in translation to natural languages whose grammatic impose change in the order of the sentence, like german language.

提交回复
热议问题