Programing

긴 여러 줄 문자열을 만드는 Pythonic 방법

lottogame 2020. 9. 27. 12:38
반응형

긴 여러 줄 문자열을 만드는 Pythonic 방법


매우 긴 쿼리가 있습니다. 파이썬에서 여러 줄로 나누고 싶습니다. JavaScript에서이를 수행하는 방법은 여러 문장을 사용하고이를 +연산자 와 결합하는 것입니다 (가장 효율적인 방법이 아닐 수도 있지만이 단계의 성능에 대해서는 실제로 관심이 없습니다. 코드 가독성 만 있습니다) . 예:

var long_string = 'some text not important. just garbage to' +
                  'illustrate my example';

파이썬에서 비슷한 것을 시도했지만 작동하지 않아서 \긴 문자열을 분할했습니다. 그러나 이것이 유일하고 / 최고 / pythonic 한 방법인지 확실하지 않습니다. 어색해 보인다. 실제 코드 :

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 = ' + account_id + ' AND'\
    'record_def.account_id=' + account_id + ' AND'\
    'def_id=' + def_id

여러 줄 문자열에 대해 이야기하고 있습니까? 쉽게 시작하고 끝낼 때 세 개의 따옴표를 사용하십시오.

s = """ this is a very
        long string if I had the
        energy to type more and more ..."""

작은 따옴표도 사용할 수 있으며 (물론 시작과 끝에 3 개) 결과 문자열을 s다른 문자열과 마찬가지로 처리 할 수 ​​있습니다.

참고 : 모든 문자열과 마찬가지로 시작 및 끝 따옴표 사이의 모든 것이 문자열의 일부가되므로이 예제에는 선행 공백이 있습니다 (@ root45가 지적한대로). 이 문자열은 또한 공백과 개행을 모두 포함합니다.

즉 :

' this is a very\n        long string if I had the\n        energy to type more and more ...'

마지막으로 다음과 같이 Python에서 긴 줄을 구성 할 수도 있습니다.

 s = ("this is a very"
      "long string too"
      "for sure ..."
     )

것이다 없는 여분의 공백이나 개행 (이 블랭크 스킵 효과가 발생 될지 나타내는 의도적 예이다)을 포함한다 :

'this is a verylong string toofor sure ...'

쉼표가 필요하지 않습니다. 결합 할 문자열을 한 쌍의 괄호로 묶고 필요한 공백과 줄 바꿈을 고려하십시오.


여러 줄 문자열을 원하지 않고 긴 단일 줄 문자열 만있는 경우 괄호를 사용할 수 있습니다. 문자열 세그먼트 사이에 쉼표를 포함하지 않는지 확인하면 튜플이됩니다.

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 = '+account_id+' AND'
         ' record_def.account_id='+account_id+' AND'
         ' def_id='+def_id)

구성하는 것과 같은 SQL 문에서 여러 줄 문자열도 괜찮습니다. 그러나 여러 줄 문자열에 포함되는 추가 공백이 문제가 될 경우 원하는 것을 달성하는 좋은 방법이 될 것입니다.


\나를 위해 작품으로 줄을 끊 습니다. 다음은 예입니다.

longStr = "This is a very long string " \
        "that I wrote to help somebody " \
        "who had a question about " \
        "writing long strings in Python"

나는 이것에 만족했다.

string = """This is a
very long string,
containing commas,
that I split up
for readability""".replace('\n',' ')

긴 문자열을 작성할 때 일반적으로 SQL 쿼리 작성과 같은 작업을 수행하는 것으로 나타났습니다.이 경우 가장 좋습니다.

query = ' '.join((  # note double parens, join() takes an iterable
    "SELECT foo",
    "FROM bar",
    "WHERE baz",
))

Levon이 제안한 것은 좋지만 실수에 취약 할 수 있습니다.

query = (
    "SELECT foo"
    "FROM bar"
    "WHERE baz"
)

query == "SELECT fooFROM barWHERE baz"  # probably not what you want

"" "표기법을 사용할 때에서 변수를 연결할 수도 있습니다.

foo = '1234'

long_string = """fosdl a sdlfklaskdf as
as df ajsdfj asdfa sld
a sdf alsdfl alsdfl """ +  foo + """ aks
asdkfkasdk fak"""

편집 : 명명 된 params 및 .format ()으로 더 나은 방법을 찾았습니다.

body = """
<html>
<head>
</head>
<body>
    <p>Lorem ipsum.</p>
    <dl>
        <dt>Asdf:</dt>     <dd><a href="{link}">{name}</a></dd>
    </dl>
    </body>
</html>
""".format(
    link='http://www.asdf.com',
    name='Asdf',
)

print(body)

Python> = 3.6에서는 형식화 된 문자열 리터럴 (f 문자열)을 사용할 수 있습니다.

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}'''

이 접근 방식은 다음을 사용합니다.

  • 초기 줄 바꿈을 피하기 위해 백 슬래시 하나만
  • 삼중 따옴표로 묶인 문자열을 사용하여 내부 구두점이 거의 없음
  • textwrap inspect 모듈을 사용하여 로컬 들여 쓰기를 제거 합니다.
  • account_iddef_id변수에 python 3.6 형식의 문자열 보간 ( 'f')을 사용합니다 .

이 방법은 나에게 가장 비단뱀처럼 보입니다.

# import textwrap  # See update to answer below
import inspect

# query = textwrap.dedent(f'''\
query = inspect.cleandoc(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}'''
)

업데이트 : 1/29/2019 inspect.cleandoc대신 @ShadowRanger의 제안을 사용하십시오.textwrap.dedent


예를 들면 :

sql = ("select field1, field2, field3, field4 "
       "from table "
       "where condition1={} "
       "and condition2={}").format(1, 2)

Output: 'select field1, field2, field3, field4 from table 
         where condition1=1 and condition2=2'

condition의 값이 문자열이어야하는 경우 다음과 같이 할 수 있습니다.

sql = ("select field1, field2, field3, field4 "
       "from table "
       "where condition1='{0}' "
       "and condition2='{1}'").format('2016-10-12', '2017-10-12')

Output: "select field1, field2, field3, field4 from table where
         condition1='2016-10-12' and condition2='2017-10-12'"

개인적으로 Python에서 원시 SQL 쿼리를 작성하는 가장 좋은 (간단하고 안전하며 Pythonic) 방법은 다음과 같습니다. 특히 Python의 sqlite3 모듈을 사용할 때 그렇습니다 .

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

장점

  • 깔끔하고 간단한 코드 (Pythonic!)
  • SQL 주입으로부터 안전
  • Python 2 및 Python 3 모두와 호환됩니다 (결국 Pythonic입니다).
  • 문자열 연결이 필요하지 않습니다.
  • 각 줄의 맨 오른쪽 문자가 공백인지 확인할 필요가 없습니다.

단점

  • 쿼리의 변수가 ?자리 표시 자로 대체되기 때문에 쿼리에 ?변수가 많을 때 어떤 Python 변수로 대체 될 것인지 추적하기가 조금 어려울 수 있습니다.

여기에textwrap.dedent 설명 된대로 긴 문자열에 가장 적합한 것을 찾습니다 .

def create_snippet():
    code_snippet = textwrap.dedent("""\
        int main(int argc, char* argv[]) {
            return 0;
        }
    """)
    do_something(code_snippet)

다른 사람들은 이미 괄호 방법을 언급했지만 괄호로 추가하고 싶습니다. 인라인 주석이 허용됩니다.

각 조각에 대한 설명 :

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

계속 후 댓글이 허용되지 않음 :

백 슬래시 줄 연속 ( \)을 사용하는 경우 주석이 허용되지 않습니다. 당신은 받게됩니다 SyntaxError: unexpected character after line continuation character오류가 발생했습니다.

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

Regex 문자열에 대한 더 나은 주석 :

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)

나는 보통 다음과 같은 것을 사용합니다.

text = '''
    This string was typed to be a demo
    on how could we write a multi-line
    text in Python.
'''

각 줄의 성가신 공백을 제거하려면 다음과 같이 할 수 있습니다.

text = '\n'.join(line.lstrip() for line in text.splitlines())

실제 코드는 "선"의 끝에 공백 누락, 작동하지합니다 (예 : role.descr as roleFROM...)

여러 줄 문자열에 대한 삼중 따옴표가 있습니다.

string = """line
  line2
  line3"""

줄 바꿈과 추가 공백이 포함되지만 SQL의 경우 문제가되지 않습니다.


You can also place the sql-statement in a seperate file action.sql and load it in the py file with

with open('action.sql') as f:
   query = f.read()

So the sql-statements will be separated from the python code. If there are parameters in the sql statement which needs to be filled from python, you can use string formating (like %s or {field})


"À la" Scala way (but I think is the most pythonic way as OQ demands):

description = """
            | The intention of this module is to provide a method to 
            | pass meta information in markdown_ header files for 
            | using it in jinja_ templates. 
            | 
            | Also, to provide a method to use markdown files as jinja 
            | templates. Maybe you prefer to see the code than 
            | to install it.""".replace('\n            | \n','\n').replace('            | ',' ')

If you want final str without jump lines, just put \n at the start of the first argument of the second replace:

.replace('\n            | ',' ')`.

Note: the white line between "...templates." and "Also, ..." requires a whitespace after the |.


I use a recursive function to build complex SQL Queries. This technique can generally be used to build large strings while maintaining code readability.

# Utility function to recursively resolve SQL statements.
# CAUTION: Use this function carefully, Pass correct SQL parameters {},
# TODO: This should never happen but check for infinite loops
def resolveSQL(sql_seed, sqlparams):
    sql = sql_seed % (sqlparams)
    if sql == sql_seed:
        return ' '.join([x.strip() for x in sql.split()])
    else:
        return resolveSQL(sql, sqlparams)

P.S: Have a look at the awesome python-sqlparse library to pretty print SQL queries if needed. http://sqlparse.readthedocs.org/en/latest/api/#sqlparse.format


Another option that I think is more readable when the code (e.g variable) is indented and the output string should be a one liner (no newlines):

def some_method():

    long_string = """
a presumptuous long string 
which looks a bit nicer 
in a text editor when
written over multiple lines
""".strip('\n').replace('\n', ' ')

    return long_string 

I like this approach because it privileges reading. In cases where we have long strings there is no way! Depending on the level of indentation you are in and still limited to 80 characters per line... Well... No need to say anything else. In my view the python style guides are still very vague. I took the @Eero Aaltonen approach because it privileges reading and common sense. I understand that style guides should help us and not make our lives a mess. Thanks!

class ClassName():
    def method_name():
        if condition_0:
            if condition_1:
                if condition_2:
                    some_variable_0 =\
"""
some_js_func_call(
    undefined, 
    {
        'some_attr_0': 'value_0', 
        'some_attr_1': 'value_1', 
        'some_attr_2': '""" + some_variable_1 + """'
    }, 
    undefined, 
    undefined, 
    true
)
"""

Hey try something like this hope it works, like in this format it will return you a continuous line like you have successfully enquired about this property`

"message": f'you have successfully inquired about '
           f'{enquiring_property.title} Property owned by '
           f'{enquiring_property.client}'

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


tl;dr: Use """\ and """ to wrap the string, as in

string = """\
This is a long string
spanning multiple lines.
"""

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

Usage: thingy [OPTIONS]
     -h                        Display this usage message
     -H hostname               Hostname to connect to

Generally, I use list and join for multi-line comments/string.

lines = list()
lines.append('SELECT action.enter code here descr as "action", ')
lines.append('role.id as role_id,')
lines.append('role.descr as role')
lines.append('FROM ')
lines.append('public.role_action_def,')
lines.append('public.role,')
lines.append('public.record_def, ')
lines.append('public.action')
query = " ".join(lines)

you can use any string to join all this list element like '\n'(newline) or ','(comma) or ''(space)

Cheers..!!

참고URL : https://stackoverflow.com/questions/10660435/pythonic-way-to-create-a-long-multi-line-string

반응형