Ответ 1
Не встроенная функция, а функция в стандартной библиотеке: textwrap.dedent()
>>> print(textwrap.dedent(s))
Controller = require 'controller'
class foo
view: 'baz'
class: 'bar'
constructor: ->
Controller.mix @
Скажем, у меня есть строка
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 @"
Не встроенная функция, а функция в стандартной библиотеке: textwrap.dedent()
>>> print(textwrap.dedent(s))
Controller = require 'controller'
class foo
view: 'baz'
class: 'bar'
constructor: ->
Controller.mix @
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])