Pythonic way to create a long multi-line string

后端 未结 27 1679
滥情空心
滥情空心 2020-11-22 00:47

I have a very long query. I would like to split it in several lines in Python. A way to do it in JavaScript would be using several sentences and joining them with a +<

相关标签:
27条回答
  • 2020-11-22 01:02

    From the official python documentation:

    String literals can span multiple lines. One way is using triple-quotes: """...""" or '''...'''. End of lines are automatically included in the string, but it’s possible to prevent this by adding a \ at the end of the line. The following example:

    print("""\
    Usage: thingy [OPTIONS]
         -h                        Display this usage message
         -H hostname               Hostname to connect to
    """)
    

    produces the following output (note that the initial newline is not included):

    0 讨论(0)
  • 2020-11-22 01:03

    I personally find the following to be the best (simple, safe and Pythonic) way to write raw SQL queries in Python, especially when using Python's sqlite3 module:

    query = '''
        SELECT
            action.descr as action,
            role.id as role_id,
            role.descr as role
        FROM
            public.role_action_def,
            public.role,
            public.record_def,
            public.action
        WHERE
            role.id = role_action_def.role_id
            AND record_def.id = role_action_def.def_id
            AND action.id = role_action_def.action_id
            AND role_action_def.account_id = ?
            AND record_def.account_id = ?
            AND def_id = ?
    '''
    vars = (account_id, account_id, def_id)   # a tuple of query variables
    cursor.execute(query, vars)   # using Python's sqlite3 module
    

    Pros

    • Neat and simple code (Pythonic!)
    • Safe from SQL injection
    • Compatible with both Python 2 and Python 3 (it's Pythonic after all)
    • No string concatenation required
    • No need to ensure that the right-most character of each line is a space

    Cons

    • Since variables in the query are replaced by the ? placeholder, it may become a little difficult to keep track of which ? is to be substituted by which Python variable when there are lots of them in the query.
    0 讨论(0)
  • 2020-11-22 01:09

    Others have mentioned the parentheses method already, but I'd like to add that with parentheses, inline comments are allowed.

    Comment on each fragment:

    nursery_rhyme = (
        'Mary had a little lamb,'          # Comments are great!
        'its fleece was white as snow.'
        'And everywhere that Mary went,'
        'her sheep would surely go.'       # What a pesky sheep.
    )
    

    Comment not allowed after continuation:

    When using backslash line continuations (\ ), comments are not allowed. You'll receive a SyntaxError: unexpected character after line continuation character error.

    nursery_rhyme = 'Mary had a little lamb,' \  # These comments
        'its fleece was white as snow.'       \  # are invalid!
        'And everywhere that Mary went,'      \
        'her sheep would surely go.'
    # => SyntaxError: unexpected character after line continuation character
    

    Better comments for Regex strings:

    Based on the example from https://docs.python.org/3/library/re.html#re.VERBOSE,

    a = re.compile(
        r'\d+'  # the integral part
        r'\.'   # the decimal point
        r'\d*'  # some fractional digits
    )
    
    # Using VERBOSE flag, IDE usually can't syntax highight the string comment.
    a = re.compile(r"""\d +  # the integral part
                       \.    # the decimal point
                       \d *  # some fractional digits""", re.X)
    
    0 讨论(0)
  • 2020-11-22 01:10

    I found myself happy with this one:

    string = """This is a
    very long string,
    containing commas,
    that I split up
    for readability""".replace('\n',' ')
    
    0 讨论(0)
  • 2020-11-22 01:12

    In Python >= 3.6 you can use Formatted string literals (f string)

    query= f'''SELECT   action.descr as "action"
        role.id as role_id,
        role.descr as role
        FROM
        public.role_action_def,
        public.role,
        public.record_def,
        public.action
        WHERE role.id = role_action_def.role_id AND
        record_def.id = role_action_def.def_id AND
        action.id = role_action_def.action_id AND
        role_action_def.account_id = {account_id} AND
        record_def.account_id = {account_id} AND
        def_id = {def_id}'''
    
    0 讨论(0)
  • 2020-11-22 01:12

    As a general approach to long strings in Python you can use triple quotes, split and join:

    _str = ' '.join('''Lorem ipsum dolor sit amet, consectetur adipiscing 
            elit, sed do eiusmod tempor incididunt ut labore et dolore 
            magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation 
            ullamco laboris nisi ut aliquip ex ea commodo.'''.split())
    

    Output:

    'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo.'
    

    With regard to OP's question relating to a SQL query, the answer below disregards the correctness of this approach to building SQL queries and focuses only on building long strings in a readable and aesthetic way without additional imports. It also disregards the computational load this entails.

    Using triple quotes we build a long and readable string which we then break up into a list using split() thereby stripping the whitespace and then join it back together with ' '.join(). Finally we insert the variables using the format() command:

    account_id = 123
    def_id = 321
    
    _str = '''
        SELECT action.descr AS "action", role.id AS role_id, role.descr AS role 
        FROM public.role_action_def, public.role, public.record_def, public.action
        WHERE role.id = role_action_def.role_id 
        AND record_def.id = role_action_def.def_id 
        AND' action.id = role_action_def.action_id 
        AND role_action_def.account_id = {} 
        AND record_def.account_id = {} 
        AND def_id = {}
        '''
    
    query = ' '.join(_str.split()).format(account_id, account_id, def_id)
    
    

    Produces:

    SELECT action.descr AS "action", role.id AS role_id, role.descr AS role FROM public.role_action_def, public.role, public.record_def, public.action WHERE role.id = role_action_def.role_id AND record_def.id = role_action_def.def_id AND\' action.id = role_action_def.action_id AND role_action_def.account_id = 123 AND record_def.account_id=123 AND def_id=321
    

    Edit: This approach is not in line with PEP8 but I find it useful at times

    0 讨论(0)
提交回复
热议问题