programing

내포된 f-스트링

lovejava 2023. 5. 19. 23:52

내포된 f-스트링

David Beazley의 트윗 덕분최근에 새로운 Python 3.6 f-string도 중첩될 수 있다는 것을 알게 되었습니다.

>>> price = 478.23
>>> f"{f'${price:0.2f}':*>20s}"
'*************$478.23'

또는:

>>> x = 42
>>> f'''-{f"""*{f"+{f'.{x}.'}+"}*"""}-'''
'-*+.42.+*-'

저는 이것이 가능하다는 것에 놀랐지만, 그것이 얼마나 실용적인지 놓치고 있습니다, nesting f-string은 언제 유용할까요?어떤 활용 사례를 다룰 수 있습니까?

참고: PEP 자체는 f-string 중첩에 대해 언급하지 않지만, 특정 테스트 사례가 있습니다.

포맷된 문자열 리터럴이 중첩을 허용하지 않는다고 생각합니다(네스팅을 통해, 나는 그것을 의미한다고 생각합니다).f'{f".."}'사례를 것이라고 합니다.는 가능한 사용 사례를 신중하게 고려한 결과이며, 사양을 준수하기 위해 허용될 것이라고 확신합니다.

이 사양은 괄호 안에서 전체 Python 표현식*을 지원한다고 명시되어 있습니다.형식화된 문자열 리터럴은 실제로 런타임에 평가되는 표현식이라고도 합니다(여기와 여기 참조).따라서 형식화된 문자열 리터럴을 다른 형식화된 문자열 리터럴 내부의 식으로 허용하는 것이 타당하며, 이는 Python 표현식에 대한 전체 지원을 부정하는 것을 금지합니다.

문서에 언급된 사용 사례를 찾을 수 없고 테스트 제품군에서만 테스트 사례를 찾을 수 있는 것은 이는 구현의 좋은 (부작용) 효과일 수 있으며 사용 사례에 동기를 부여하는 것이 아니기 때문입니다.


사실, 세 가지 예외를 제외하고는:빈 식을 사용할 수 없으며 람다 식은 명시적 괄호로 둘러싸야 합니다.같은 따옴표로 문자열을 중첩하면 구문 오류가 반환됩니다.

이것은 포맷 파라미터를 동일한 라인에 전달하여 f-string 사용을 단순화하기 위한 것으로 생각합니다.

예:

>>> import decimal
>>> width = 10
>>> precision = 4
>>> value = decimal.Decimal("12.34567")
>>> f"result: {value:{width}.{precision}}"
'result:      12.35'

물론 프로그래머들이 절대 읽을 수 없는 코드를 작성할 수 있게 해주지만, 목적은 그게 아닙니다 :)

저는 사실 방금 비슷한 것을 발견했고 공유하려고 생각했습니다.

저의 구체적인 사례는 조건부로 매우 다른 값을 가져야 하지만 일부 fstring이 동일한 큰 dirty sql 문입니다(다른 곳에서도 사용됨).

여기 제가 의미하는 것에 대한 간단한 예가 있습니다.선택하는 콜은 상관없이 동일하지만(다른 쿼리에서도 사용됨) 테이블 이름은 그룹에 따라 다르며 루프에서 수행할 수 있는 것이 없습니다.

을 해야 함mycols=mycols.in str2가 개 때 .

나는 이것이 효과가 있을지 확신할 수 없었지만 그것이 효과가 있어서 기뻤습니다.그것이 얼마나 비단결적인지에 대해 나는 정말 확신할 수 없습니다.

mycols='col_a,col_b'

str1 = "select {mycols} from {mytable} where group='{mygroup}'".format(mycols=mycols,mytable='{mytable}',mygroup='{mygroup}')

group = 'group_b'

if group == 'group_a':
    str2 = str1.format(mytable='tbl1',mygroup=group)
elif group == 'group_b':
    str2 = str1.format(mytable='a_very_different_table_name',mygroup=group)

print(str2)

대괄호 안에 하기 위해 입니다.{}예를 들어, 사전을 색인화하려면 문자열이 필요합니다.

그래서 ML 프로젝트에서 다음과 같은 코드로 사용하게 되었습니다.

scores = dict()
scores[f'{task}_accuracy'] = 100. * n_valid / n_total
print(f'{task}_accuracy: {scores[f"{task}_accuracy"]}')

애완동물 프로젝트를 하면서 나는 나만의 DB 라이브러리를 작성하면서 옆길로 빠져나갔습니다.제가 발견한 것은 다음과 같습니다.

>>> x = dict(a = 1, b = 2, d = 3)
>>> z = f"""
    UPDATE TABLE 
        bar 
    SET 
        {", ".join([ f'{k} = ?'     for k in x.keys() ])} """.strip()
>>> z
'UPDATE TABLE 
    bar 
SET 
    a = ?, b = ?, d = ?  '

저도 이것에 놀랐고 솔직히 생산코드에서 이런 일을 할 수 있을지 확신할 수 없지만 생산코드에서 다른 일은 많이 하지 않겠다고 말했습니다.

저는 둥지를 틀면 3학기를 할 때 유용하다는 것을 알게 되었습니다.가독성에 대한 당신의 의견은 다양하겠지만, 저는 이 한 줄기가 매우 유용하다는 것을 알았습니다.

logger.info(f"No program name in subgroups file. Using {f'{prg_num} {prg_orig_date}' if not prg_name else prg_name}")

따라서, 내포에 대한 테스트는 다음과 같습니다.

  • 값이 재사용됩니까?(식 재사용을 위한 변수)
  • 표정이 명확합니까?(복잡도 이하)

저는 그것을 통화 포맷에 사용합니다.주어진 값은 다음과 같습니다.

a=1.23
b=45.67

선두 달러와 소수점이 정렬된 형식을 지정합니다.

 $1.23
$45.67

f-string으로 지정 자F-문로형 지정식열f"${value:5.2f}"다음을 얻을 수 있습니다.

$ 1.23
$45.67

가끔은 괜찮지만 항상은 아닙니다. f-스트링f"${f'${value:.2f}':>6}"정확한 형식을 제공합니다.

 $1.23
$45.67

구현 예와 함께 유용한 경우의 간단한 예입니다. 때로는 형식도 변수가 됩니다.

num = 3.1415
fmt = ".2f"
print(f"number is {num:{fmt}}")

내포된 f-string 대 형식 지정자의 평가된 표현식

이 질문은 "외부" f-string의 평가된 표현의 내부에 f-string을 사용하여 동기를 부여하는 사용 사례에 관한 것입니다.

이는 평가된 식을 f-string 형식 지정자 내에 표시할 수 있는 기능과 다릅니다.이 후자의 기능은 (1) 중첩된 곱슬곱슬한 중괄호를 포함하므로 사람들이 이 게시물을 보는 이유일 수 있고 (2) 중첩된 f-string이 f-string의 다른 곱슬곱슬한 표현 내에 있는 것처럼 형식 지정자 내에서 허용되기 때문에 이 질문에 매우 유용하고 다소 관련이 있습니다.

F-string 중첩은 한 줄로 연결하는 데 도움이 됩니다.

내포된 f-스트링을 허용하는 동기는 분명하지 않지만, 내포는 "원 라이너"가 필요하거나 원하는 모호한 경우에 도움이 될 수 있습니다(예: 람다 식, 이해,python -c명령을 입력합니다.예:

print('\n'.join([f"length of {x/3:g}{'.'*(11 - len(f'{x/3:g}'))}{len(f'{x/3:g}')}" for x in range(10)]))

하나의 라이너가 필요하지 않은 경우, 사전에 변수를 정의한 다음 f-string의 평가된 식에서 변수 이름을 사용하여 구문 중첩을 대체할 수 있습니다(대부분의 경우는 아니지만, 중첩되지 않은 버전이 더 읽기 쉽고 유지 관리하기 쉬우며 변수 이름을 지정해야 합니다).

for x in range(10):
    to_show = f"{x/3:g}"
    string_length = len(to_show)
    padding = '.' * (11 - string_length)
    print(f"length of {to_show}{padding}{string_length}")

중첩된 평가식(예: 형식 지정자)이 유용합니다.

진정한 f-string 중첩과 대조적으로, f-string의 "형식 지정자" 내에서 평가된 표현을 허용하는 관련 기능은 다음과 같은 몇 가지 이유로 매우 유용할 수 있습니다.

  1. 여러 개의 f-backet 또는 평가된 식을 통해 형식을 공유할 수 있습니다.
  2. 형식 지정에는 실행마다 다를 수 있는 계산된 수량이 포함될 수 있습니다.

다음은 중첩된 f-문자열이 아닌 중첩된 평가 식을 사용하는 예제입니다.

import random

results = [[i, *[random.random()] * 3] for i in range(10)]
format = "2.2f"

print("category,precision,recall,f1")
for cat, precision, recall, f1 in results:
    print(f"{cat},{precision:{format}},{recall:{format}},{f1:{format}}")

그러나 이러한 중첩 사용도 구문 중첩이 필요 없는 보다 유연한(또는 더 깨끗한) 코드로 대체할 수 있습니다.

import random

results = [[i, *[random.random()] * 3] for i in range(10)]
def format(x):
    return f"{x:2.2f}"

print("category,precision,recall,f1")
for cat, precision, recall, f1 in results:
    print(f"{cat},{format(precision)},{format(recall)},{format(f1)}")

다음 중첩된 f-string 원라이너는 명령 인수 문자열을 구성하는 데 유용합니다.

cmd_args = f"""{' '.join([f'--{key} {value}' for key, value in kwargs.items()])}"""

입력하는 곳{'a': 10, 'b': 20, 'c': 30, ....}

로 우아하게 변환됩니다.--a 10 --b 20 --c 30 ...`

F 문자열에서 열린 괄호와 닫힌 괄호는 예약된 키 문자입니다.json 문자열을 빌드하기 위해 f-string을 사용하려면 괄호 문자를 이스케이프해야 합니다.당신의 경우에는 외부 부모님들만.

f"\{f'${price:0.2f}':*>20s\}"

화려한 포맷이 필요하다면, 그러한 둥지는 아마도 유용할 것입니다.

for n in range(10, 1000, 100):
    print(f"{f'n = {n:<3}':<15}| {f'|{n:>5}**2 = {n**2:<7_}'} |")

역동성을 위해 사용할 수 있습니다.예를 들어, 변수가 일부 함수의 이름으로 설정되어 있다고 가정합니다.

func = 'my_func'

그런 다음 다음과 같이 쓸 수 있습니다.

f"{f'{func}'()}" 

이 값은 다음과 같습니다.

'{}'.format(locals()[func]()) 

또는 동등하게:

'{}'.format(my_func())

언급URL : https://stackoverflow.com/questions/41215365/nested-f-strings