Подтвердить что ты не робот

У Python есть встроенная функция для отмене многострочной строки?

Скажем, у меня есть строка

s = """
    Controller = require 'controller'

    class foo
        view: 'baz'
        class: 'bar'

        constructor: ->
            Controller.mix @
"""

Каждая строка в строке теперь имеет глобальное отступы в 4 пространства. Если эта строка была объявлена ​​внутри функции, у нее будет глобальное отступы на 8 пробелов и т.д.

Есть ли у Python функция для удаления глобального левого отступа строки?

Я хотел бы, чтобы эта функция была:

Controller = require 'controller'

class foo
    view: 'baz'
    class: 'bar'

    constructor: ->
        Controller.mix @"
4b9b3361

Ответ 1

Не встроенная функция, а функция в стандартной библиотеке: textwrap.dedent()

>>> print(textwrap.dedent(s))

Controller = require 'controller'

class foo
    view: 'baz'
    class: 'bar'

    constructor: ->
        Controller.mix @

Ответ 2

textwrap.dedent() близок к тому, что вы хотите, но он не реализует то, что вы просили, потому что оно имеет ведущую новую строку. Вы можете либо обернуть dedent в функцию, которая переводит ведущую строку новой строки из s:

def my_dedent(string):
    if string and string[0] == '\n':
        string = string[1:]
    return textwrap.dedent(string)

Однако textwrap.dedent() обрабатывает строки с просто пробелами особым образом, это нормально, если вы генерируете исходный код Python из многострочного оператора с отступом, где конечное пустое значение несущественно.

Но в целом неуместно, что textwrap.dedent() удаляет лишние пробелы из строк с большим количеством пробелов, чем "максимальный отступ", удаляет пробелы из всех пробельных строк и что он отбрасывает пробелы перед закрытием """, тем более, что это поведение недокументировано и выполнено с непрозрачными регулярными выражениями.

Так как я также создаю исходный код, отличный от Python, где часто встречаются пробелы, я использую следующую процедуру. Он не обрабатывает отступ TAB, но он дает вам результат, который вы запросили, не указав новую строку, где textwrap.dedent() не работает.

def remove_leading_spaces(s, strict=False):
    '''Remove the maximum common spaces from all non-empty lines in string

Typically used to remove leading spaces from all non-empty lines in a
multiline string, preserving all extra spaces.
A leading newline (when not useing '"""\') is removed unless the strict
argument is True.

Note that if you want two spaces on the last line of the return value 
without a newline, you have to use the max indentation + 2 spaces before 
the closing """. If you just input 2 spaces that is likely to be the 
maximum indent.
    '''
    if s and not strict and s[0] == '\n':
        s = s[1:]
    lines = s.splitlines(True) # keep ends
    max_spaces = -1
    for line in lines:
        if line != '\n':
            for idx, c in enumerate(line[:max_spaces]):
                if not c == ' ':
                    break
            max_spaces = idx + 1
    return ''.join([l if l == '\n' else l[max_spaces-1:] for l in lines])