logger - python logging yaml config




파이썬 문자열 포맷팅:% vs..format (10)

Python 2.6에서는 기존 % 연산자와 약간 다른 구문을 사용하여 str.format() 메서드를 도입했습니다. 어떤 상황에서 더 낫습니까?

  1. 다음은 각 방법을 사용하고 결과가 동일하므로 차이점은 무엇입니까?

    #!/usr/bin/python
    sub1 = "python string!"
    sub2 = "an arg"
    
    a = "i am a %s" % sub1
    b = "i am a {0}".format(sub1)
    
    c = "with %(kwarg)s!" % {'kwarg':sub2}
    d = "with {kwarg}!".format(kwarg=sub2)
    
    print a    # "i am a python string!"
    print b    # "i am a python string!"
    print c    # "with an arg!"
    print d    # "with an arg!"
    
  2. 또한 문자열 형식이 파이썬에서 언제 발생합니까? 예를 들어, 로깅 수준을 HIGH로 설정하면 다음 % 작업을 수행 할 때 여전히 적중합니까? 그렇다면 이것을 피할 수있는 방법이 있습니까?

    log.debug("some debug info: %s" % some_info)
    


Python 버전이 3.6 이상인 경우 ( PEP 498 참조)

s1='albha'
s2='beta'

f'{s1}{s2:>10}'

#output
'albha      beta'

그러나 중첩 된 중괄호를 사용하면 형식에 대해 작동하지 않지만 % 는 작동합니다.

예:

>>> '{{0}, {1}}'.format(1,2)
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    '{{0}, {1}}'.format(1,2)
ValueError: Single '}' encountered in format string
>>> '{%s, %s}'%(1,2)
'{1, 2}'
>>> 

나는 버전 3.6부터 fstring을 다음과 같이 사용할 수 있다고 덧붙였다.

foo = "john"
bar = "smith"
print(f"My name is {foo} {bar}")

어느 것을 주는지

제 이름은 존 스미스입니다.

모든 것이 문자열로 변환됩니다.

mylist = ["foo", "bar"]
print(f"mylist = {mylist}")

결과:

mylist = [ 'foo', 'bar']

다른 형식의 메서드처럼 함수를 전달할 수 있습니다.

print(f'Hello, here is the date : {time.strftime("%d/%m/%Y")}')

예를 들면주는 것

안녕하세요, 날짜는 다음과 같습니다 : 16/04/2018


모듈러스 연산자 (%)가 할 수없는 것, afaik :

tu = (12,45,22222,103,6)
print '{0} {2} {1} {2} {3} {2} {4} {2}'.format(*tu)

결과

12 22222 45 22222 103 22222 6 22222

굉장히 유용하다.

또 다른 포인트 : 함수 인 format() 은 다른 함수에서 인수로 사용할 수 있습니다.

li = [12,45,78,784,2,69,1254,4785,984]
print map('the number is {}'.format,li)   

print

from datetime import datetime,timedelta

once_upon_a_time = datetime(2010, 7, 1, 12, 0, 0)
delta = timedelta(days=13, hours=8,  minutes=20)

gen =(once_upon_a_time +x*delta for x in xrange(20))

print '\n'.join(map('{:%Y-%m-%d %H:%M:%S}'.format, gen))

결과 :

['the number is 12', 'the number is 45', 'the number is 78', 'the number is 784', 'the number is 2', 'the number is 69', 'the number is 1254', 'the number is 4785', 'the number is 984']

2010-07-01 12:00:00
2010-07-14 20:20:00
2010-07-28 04:40:00
2010-08-10 13:00:00
2010-08-23 21:20:00
2010-09-06 05:40:00
2010-09-19 14:00:00
2010-10-02 22:20:00
2010-10-16 06:40:00
2010-10-29 15:00:00
2010-11-11 23:20:00
2010-11-25 07:40:00
2010-12-08 16:00:00
2010-12-22 00:20:00
2011-01-04 08:40:00
2011-01-17 17:00:00
2011-01-31 01:20:00
2011-02-13 09:40:00
2011-02-26 18:00:00
2011-03-12 02:20:00

오늘 발견했듯이 % 를 통해 문자열을 포맷하는 옛 방식은 십진법 고정 소수점 및 부동 소수점 연산을위한 Python 모듈을 Decimal 지원하지 않습니다.

예제 (파이썬 3.3.5 사용) :

#!/usr/bin/env python3

from decimal import *

getcontext().prec = 50
d = Decimal('3.12375239e-24') # no magic number, I rather produced it by banging my head on my keyboard

print('%.50f' % d)
print('{0:.50f}'.format(d))

산출:

0.00000000000000000000000312375239000000009907464850 0.00000000000000000000000312375239000000000000000000

분명히 해결 방법이있을 수 있지만 format() 메서드를 사용하는 것이 좋습니다.


파이썬> = 3.6 인 경우 F- 문자열 형식의 리터럴이 새 친구입니다.

더 간단하고 깨끗하며 성능이 좋습니다.

In [1]: params=['Hello', 'adam', 42]

In [2]: %timeit "%s %s, the answer to everything is %d."%(params[0],params[1],params[2])
448 ns ± 1.48 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [3]: %timeit "{} {}, the answer to everything is {}.".format(*params)
449 ns ± 1.42 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [4]: %timeit f"{params[0]} {params[1]}, the answer to everything is {params[2]}."
12.7 ns ± 0.0129 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

파이썬의 logging 모듈을 사용한다고 가정하면, 포맷팅을 직접하지 않고 .debug() 메소드에 인수로 문자열 형식 인수를 전달할 수 있습니다.

log.debug("some debug info: %s", some_info)

로거가 실제로 무언가를 기록하지 않는 한 포맷 작업을하지 않아도됩니다.


% 가 도움이 될 수있는 한 가지 상황은 정규 표현식을 형식화 할 때입니다. 예를 들어,

'{type_names} [a-z]{2}'.format(type_names='triangle|square')

IndexError 시킵니다. 이 경우 다음을 사용할 수 있습니다.

'%(type_names)s [a-z]{2}' % {'type_names': 'triangle|square'}

이렇게하면 정규식을 '{type_names} [az]{{2}}' 로 작성하지 않아도됩니다. 두 정규식이있을 때 유용 할 수 있습니다. 하나는 형식없이 단독으로 사용되지만 두 표현식의 연결은 형식이 지정됩니다.


% 는 내 테스트의 format 보다 더 나은 성능을 제공합니다.

테스트 코드 :

Python 2.7.2 :

import timeit
print 'format:', timeit.timeit("'{}{}{}'.format(1, 1.23, 'hello')")
print '%:', timeit.timeit("'%s%s%s' % (1, 1.23, 'hello')")

결과:

> format: 0.470329046249
> %: 0.357107877731

파이썬 3.5.2

import timeit
print('format:', timeit.timeit("'{}{}{}'.format(1, 1.23, 'hello')"))
print('%:', timeit.timeit("'%s%s%s' % (1, 1.23, 'hello')"))

결과

> format: 0.5864730989560485
> %: 0.013593495357781649

파이썬 2에서는 파이썬 3에서 차이가 작지만 %format 보다 훨씬 빠릅니다.

감사합니다 @ 크리스 Cogdon 샘플 코드입니다.







string-formatting