文字列があるとしましょう
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 sourceを生成する場合、末尾の空白は重要ではありません)。
ただし、一般に、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])
_
この質問にはすでに回答済みですが、次の方法もあります。
import inspect
def test():
t = """
some text
"""
return inspect.cleandoc(t)
print(test())