Вставить новую строку после знака равенства в самодокументированной f-строке в python3 .8 - PullRequest
4 голосов
/ 09 мая 2020

В python3 .8 появилась новая функция самодокументирующиеся строки формата . Где обычно это делается:

>>> x = 10.583005244
>>> print(f"x={x}")
x=10.583005244
>>> 

Теперь это можно сделать с меньшим количеством повторений:

>>> x = 10.583005244
>>> print(f"{x=}")
x=10.583005244
>>> 

Это очень хорошо работает для однострочных строковых представлений. Но рассмотрим следующий сценарий:

>>> import numpy as np
>>> some_fairly_long_named_arr = np.random.rand(4,2)
>>> print(f"{some_fairly_long_named_arr=}")
some_fairly_long_named_arr=array([[0.05281443, 0.06559171],
       [0.13017109, 0.69505908],
       [0.60807431, 0.58159127],
       [0.92113252, 0.4950851 ]])
>>> 

Здесь первая строка не выравнивается, что (возможно) нежелательно. Я бы предпочел вывод следующего:

>>> import numpy as np
>>> some_fairly_long_named_arr = np.random.rand(4,2)
>>> print(f"some_fairly_long_named_arr=\n{some_fairly_long_named_arr!r}")
some_fairly_long_named_arr=
array([[0.06278696, 0.04521056],
       [0.33805303, 0.17155518],
       [0.9228059 , 0.58935207],
       [0.80180669, 0.54939958]])
>>> 

Здесь первая строка вывода также выровнена, но это лишает смысла повторение имени переменной дважды в операторе печати. ​​

Примером является массив numpy, но это мог быть pandas фрейм данных и c.

Следовательно, мой вопрос: можно ли вставить символ новой строки после знака = в самодокументированных строках?

Я пытался добавить его вот так, но это не работает:

>>> print(f"{some_fairly_long_named_arr=\n}")
SyntaxError: f-string expression part cannot include a backslash

Я прочитал документы на формат-спецификация-мини-язык , но большая часть форматирования там работает только для простых типов данных, таких как целые числа, и мне не удалось добиться то, что я хотел, используя те, которые работают.

Извините за длинное описание.

Ответы [ 2 ]

1 голос
/ 09 мая 2020

Совсем не рекомендовал бы это, но ради возможности:

import numpy as np

_old_array2string = np.core.arrayprint._array2string

def _array2_nice_string(*args, **kwargs):
    non_nice_string = _old_array2string(*args, **kwargs)

    dimension_strings = non_nice_string.split("\n")

    if len(dimension_strings) > 1:
        dimension_string = dimension_strings[1]
        dimension_indent = len(dimension_string) - len(dimension_string.lstrip())

        return "\n" + " " * dimension_indent + non_nice_string

    return non_nice_string

np.core.arrayprint._array2string = _array2_nice_string

Выводит для:

some_fairly_long_named_arr = np.random.rand(2, 2)
print(f"{some_fairly_long_named_arr=}")
some_fairly_long_named_arr=array(
       [[0.95900608, 0.79367873],
       [0.58616975, 0.17757661]])

и

some_fairly_long_named_arr = np.random.rand(1, 2)
print(f"{some_fairly_long_named_arr=}")

some_fairly_long_named_arr=array([[0.62492772, 0.80453153]]).

Я сделал так, что если первое измерение 1, оно сохраняется в той же строке.

Существует не внутренний метод np.array2string, который я пытался переназначить, но у меня так и не получилось. Если бы кто-то мог найти способ переназначить эту функцию publi c вместо этой внутренней, я бы предположил, что это сделало бы это решение намного чище.

0 голосов
/ 12 мая 2020

Я нашел способ выполнить sh то, что я хотел, после прочтения CPython источника :

import numpy as np
some_fairly_long_named_arr = np.random.rand(4, 2)
print(f"""{some_fairly_long_named_arr =
}""")

Что дает:

some_fairly_long_named_arr = 
array([[0.23560777, 0.96297907],
       [0.18882751, 0.40712246],
       [0.61351814, 0.1981144 ],
       [0.27115495, 0.72303859]])

Я бы предпочел решение, которое работало бы в одной строке, но на данный момент это единственный способ. Возможно, другой способ будет реализован в более поздней версии python.

Однако обратите внимание, что отступ в строке продолжения должен быть удален для вышеупомянутого метода, как таковой:

    # ...some code with indentation...
    print(f"""{some_fairly_long_named_arr =
}""")
    # ...more code with indentation...

В противном случае выравнивание первой строки снова нарушается.

Я пробовал использовать inspect.cleando c и textwrap.dedent , чтобы облегчить это, но мог не удается исправить проблему отступа. Но, возможно, это предмет другого вопроса.

...