Dize biçimlendirme:% vs. .format


1349

Python 2.6 str.format(), mevcut %operatörden biraz farklı bir sözdizimiyle yöntemi tanıttı . Hangisi daha iyi ve hangi durumlar için?

  1. Aşağıdakiler her yöntemi kullanır ve aynı sonuca sahiptir, bu yüzden fark nedir?

    #!/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. Ayrıca Python'da dize biçimlendirmesi ne zaman gerçekleşir? Örneğin, kayıt seviyem YÜKSEK olarak ayarlanmışsa, yine de aşağıdaki %işlemi gerçekleştirmek için bir darbe alır mıyım? Ve eğer öyleyse, bundan kaçınmanın bir yolu var mı?

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


2
Yeni başlayanlar için: İşte her iki stili de öğreten çok güzel bir öğretici . Şahsen eski %stili daha sık kullanıyorum, çünkü stilin gelişmiş yeteneklerine ihtiyacınız yoksa format(), %stil genellikle çok daha uygundur.
Lutz Prechelt

2
Başvuru için: Daha yeni format()biçimlendirme stili ve eski %tabanlı biçimlendirme stili için Python 3 belgeleri .
Lutz Prechelt


1
İkinci sorunuza cevap vermek için, 3.2'den beri özel bir biçimlendirici kullanıyorsanız {} biçimini kullanabilirsiniz (bkz. Docs.python.org/3/library/logging.html#logging.Formatter )
yanjost

Yanıtlar:


953

İlk sorunuzu cevaplamak için ... .formatbirçok yönden daha karmaşık görünüyor. Hakkında can sıkıcı bir şey %, bir değişkeni veya bir tupu nasıl alabileceğidir. Aşağıdakilerin her zaman işe yarayacağını düşünürdünüz:

"hi there %s" % name

yine de, eğer nameolursa (1, 2, 3), atar TypeError. Her zaman yazdırıldığından emin olmak için yapmanız gerekenler

"hi there %s" % (name,)   # supply the single argument as a single-item tuple

ki bu sadece çirkin. .formatbu sorunları yok. Ayrıca verdiğiniz ikinci örnekte, .formatörnek çok daha temiz görünüyor.

Neden kullanmıyorsun?

  • bilmiyorum (bunu okumadan önce ben)
  • Python 2.5 ile uyumlu olmak zorunda

İkinci sorunuzu cevaplamak için, dize biçimlendirme diğer dize işlemleriyle aynı anda gerçekleşir - dize biçimlendirme ifadesi değerlendirildiğinde. Ve tembel bir dil olmayan Python, işlevleri çağırmadan önce ifadeleri değerlendirir, bu nedenle log.debugörneğinizde, ifade "some debug info: %s"%some_infoönce değerlendirilir, örneğin "some debug info: roflcopters are active", bu dize geçirilir log.debug().


113
ne dersin"%(a)s, %(a)s" % {'a':'test'}
ted

128
İçin zaman israf olacağını Not log.debug("something: %s" % x)ama değil log.debug("something: %s", x) dize biçimlendirme yönteminde ele alınacak ve kayıt edilmedi eğer performans isabet almazsınız. Her zaman olduğu gibi, Python ihtiyaçlarınızı öngörüyor =)
darkfeline

63
ted: aynı şeyi yapmak için daha kötü görünen bir kesmek '{0}, {0}'.format('test').
uçan koyun

19
Mesele şu ki: Yeni sözdiziminin öğelerin yeniden sıralanmasına izin verdiği yinelenen argüman tartışmalı bir noktadır: Eski sözdizimi ile de aynısını yapabilirsiniz. Çoğu insan bunun aslında Ansi C99 Std'de tanımlandığını bilmiyor! Yer tutucular içindeki gösterimin son bir kopyasına man sprintfgöz $%
atın

29
@cfi: printf("%2$d", 1, 3)"3" çıktısını almak gibi bir şey ifade ediyorsanız, bu CIX yerine POSIX'te belirtilir. Not verdiğiniz tam man sayfası, "C99 standardı '$'… kullanarak stili içermiyor".
Thanatos

307

Modulo operatörünün (%) yapamayacağı bir şey, afaik:

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

sonuç

12 22222 45 22222 103 22222 6 22222

Çok kullanışlı.

Başka bir nokta:, format()bir işlev olarak, diğer işlevlerde bağımsız değişken olarak kullanılabilir:

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))

Sonuçlar:

['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

17
Eski stil biçimlendirmesini mapbiçim kadar kolay kullanabilirsiniz . map('some_format_string_%s'.__mod__, some_iterable)
agf

3
@cfi: lütfen yukarıdaki örneği C99'da yeniden yazarak haklı olduğunuzu kanıtlayın
MarcH

9
@MarcH: ile printf("%2$s %1$s\n", "One", "Two");derlendi gcc -std=c99 test.c -o test, çıktı Two One. Ama düzeltilmiş duruyorum: Aslında bir POSIX uzantısı ve C değil. Onu tekrar gördüğümü düşündüğüm C / C ++ standardında tekrar bulamıyorum. Kod 'c90' std bayrağıyla bile çalışır. sprintfsayfa . Bu onu listelemez, ancak kütüphanelerin bir üst küme uygulamasına izin verir. Benim asıl argüman yerine hala geçerli ColanPosix
CFI

8
Buradaki ilk yorumum bu cevap için geçerli değil. İfadeden pişmanım. Python'da, %yer tutucuları yeniden sıralamak için modulo operatörünü kullanamayız . Burada hala yorum tutarlılığı uğruna ilk yorumu silmek istemiyorum. Burada öfkemi havalandırdığım için özür dilerim. Eski sözdiziminin buna izin vermeyeceği sıkça yapılan açıklamaya yöneliktir. Tamamen yeni bir sözdizimi oluşturmak yerine std Posix uzantılarını tanıtabilirdik. İkisine de sahip olabiliriz.
cfi

17
'modulo', bir bölünmeden sonra kalanları değerlendiren operatörü ifade eder. bu durumda yüzde işareti bir modulo operatörü değildir.
Ahtapot

148

Python'un loggingmodülünü kullandığınızı varsayarsak , dize biçimlendirme bağımsız değişkenlerini .debug()biçimlendirmeyi kendiniz yapmak yerine yönteme bağımsız değişken olarak iletebilirsiniz :

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

bu, logger gerçekten bir şey kaydetmediği sürece biçimlendirme yapmaktan kaçınır.


10
Bu, şimdi öğrendiğim bazı yararlı bilgiler. Ana sorudan ayrı göründüğü için kendi sorusuna sahip olmadığı üzücü. Yazık ki OP sorusunu iki ayrı soruya bölmedi.
snth

12
Dict biçimlendirmesini şu şekilde kullanabilirsiniz: log.debug("some debug info: %(this)s and %(that)s", dict(this='Tom', that='Jerry')) Ancak, yeni stil .format()sözdizimini burada kullanamazsınız, hatta bir utanç olan Python 3.3'te bile.
Cito


26
Bunun birincil yararı performans değildir (dize enterpolasyonunu yapmak, günlüğe kaydetme çıktısından ne yaptığınızla karşılaştırıldığında hızlı olacaktır, örneğin bir terminalde görüntüleme, diske kaydetme) Bir günlük toplayıcıya sahipseniz, hepsinin farklı 'some_info' değerleri olsa bile size "bu hata mesajının 12 örneğini aldınız" diyebilir. Dize biçimlendirmesi, dizeyi log.debug dosyasına geçirmeden önce yapılırsa, bu mümkün değildir. Toplayıcı sadece "12 farklı günlük mesajınız vardı" diyebilir
Jonathan Hartley

7
Performans konusunda endişeleriniz varsa, dict () sınıf örneği yerine gerçek dict {} sözdizimini kullanın: doughellmann.com/2012/11/…
trojjer

119

Python 3.6 (2016) itibarıyla değişkenleri değiştirmek için f-dizelerini kullanabilirsiniz:

>>> origin = "London"
>>> destination = "Paris"
>>> f"from {origin} to {destination}"
'from London to Paris'

f"Öneki not alın . Bunu Python 3.5 veya önceki sürümlerinde denerseniz, bir SyntaxError.

Bkz. Https://docs.python.org/3.6/reference/lexical_analysis.html#f-strings


1
Bu soruya cevap vermiyor. F-dizelerinden bahseten başka bir cevap en azından performanstan bahsediyor: stackoverflow.com/a/51167833/7851470
Georgy

60

PEP 3101 , %operatörün Python 3'teki yeni, gelişmiş dize biçimlendirmesiyle değiştirilmesini önerir ve burada varsayılan değer olur.


14
Doğru: "Mevcut mekanizmalar yerinde bırakılarak geriye dönük uyumluluk sağlanabilir."; Tabii ki, dize biçimlendirmesinin yerini.format almayacak . %
Tobias

12
Hayır, BrainStorms önermesi doğrudur: "mevcut '%' yerine geçecek şekilde tasarlanmıştır". Tobias alıntısı, her iki sistemin bir süre birlikte var olacağı anlamına gelir. RTFPEP
phobie

54

Ama bütün değiştirmeye çalışırken şimdi ben bir sorun keşfettim, lütfen dikkatli ol %ile .format: kod mevcut içinde '{}'.format(unicode_string)kodlamak unicode_string çalışacağı ve muhtemelen başarısız olacaktır.

Bu Python etkileşimli oturum günlüğüne bakın:

Python 2.7.2 (default, Aug 27 2012, 19:52:55) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-48)] on linux2
; s='й'
; u=u'й'
; s
'\xd0\xb9'
; u
u'\u0439'

syalnızca bir dizedir (Python3'te 'bayt dizisi' olarak adlandırılır) ve ubir Unicode dizesidir (Python3'te 'dize' olarak adlandırılır):

; '%s' % s
'\xd0\xb9'
; '%s' % u
u'\u0439'

%Operatöre parametre olarak bir Unicode nesnesi verdiğinizde , orijinal dize Unicode olmasa bile bir Unicode dize oluşturur:

; '{}'.format(s)
'\xd0\xb9'
; '{}'.format(u)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'latin-1' codec can't encode character u'\u0439' in position 0: ordinal not in range(256)

ancak .formatişlev "UnicodeEncodeError" değerini yükseltir:

; u'{}'.format(s)
u'\xd0\xb9'
; u'{}'.format(u)
u'\u0439'

ve yalnızca orijinal dize Unicode ise bir Unicode bağımsız değişkeni ile çalışır.

; '{}'.format(u'i')
'i'

veya bağımsız değişken dizesi bir dizeye dönüştürülebilirse ('bayt dizisi' olarak adlandırılır)


12
Yeni formatyöntemin ek özelliklerine gerçekten ihtiyaç duyulmadıkça , çalışma kodunu değiştirmek için hiçbir neden yoktur ...
Tobias

kesinlikle seninle aynı fikirdeyim Tobias, ama bazen Python'un daha yeni sürümlerine yükseltme yaparken gerekli
wobmene

2
Örneğin? AFAIK, hiç gerek yoktu ; Ben muhtemelen %dize enterpolasyon hiç gidecek düşünmüyorum .
Tobias

4
Ben dizeleri için .format () işlevi% daha güvenli olduğunu düşünüyorum. Genellikle yeni başlayanların böyle hatalarını görüyorum "p1=%s p2=%d" % "abc", 2ya da "p1=%s p2=%s" % (tuple_p1_p2,). Kodlayıcının hatası olduğunu düşünebilirsiniz, ancak hızlı komut dosyası için güzel görünen ancak üretim kodu için kötü olan sadece garip hatalı sözdizimi olduğunu düşünüyorum.
wobmene

3
Ama .format () sözdizimini sevmiyorum, iyi eski ile daha mutlu olurdum %s, %02dmesela "p1=%s p2=%02d".format("abc", 2). Onlardan kaçmak için ihtiyaç duyan {{}}ve çirkin imho gibi görünen kıvırcık parantez biçimlendirmesini icat eden ve onaylayanları suçluyorum .
wobmene

35

Yine başka bir avantajı .format(cevaplarda görmüyorum): nesne özelliklerini alabilir.

In [12]: class A(object):
   ....:     def __init__(self, x, y):
   ....:         self.x = x
   ....:         self.y = y
   ....:         

In [13]: a = A(2,3)

In [14]: 'x is {0.x}, y is {0.y}'.format(a)
Out[14]: 'x is 2, y is 3'

Veya bir anahtar kelime argümanı olarak:

In [15]: 'x is {a.x}, y is {a.y}'.format(a=a)
Out[15]: 'x is 2, y is 3'

Anlayabildiğim %kadarıyla bu mümkün değil .


4
Bu, eşdeğerden daha fazla okunamayan görünüyor 'x is {0}, y is {1}'.format(a.x, a.y). Sadece a.xişlem çok maliyetli olduğunda kullanılmalıdır .
15th

13
@dtheodor bir çimdik ile ... yerine pozisyonel Tartışmanın bir anahtar kelime argüman kullanmak 'x is {a.x}, y is {a.y}'.format(a=a). Her iki örnekten daha okunabilir.
CivFan

1
@CivFan Veya, birden fazla nesneniz varsa,'x is {a.x}, y is {a.y}'.format(**vars())
Jack

1
Ayrıca aynı şekilde bu bir not: '{foo[bar]}'.format(foo={'bar': 'baz'}).
Antoine Pinsard

3
Bu, uygulamanızın kullanıcı tarafından sağlanan bir biçim dizesiyle standart bir dizi biçimlendirme seçeneği sağladığı müşteriye dönük uygulamalar için inanılmaz derecede kullanışlıdır. Bunu her zaman kullanıyorum. Örneğin yapılandırma dosyası, kullanıcının sağlayabileceği Your order, number {order[number]} was processed at {now:%Y-%m-%d %H:%M:%S}, will be ready at about {order[eta]:%H:%M:%S}veya istediği her şeyi "mesajlaşma" özelliğine sahip olacaktır . Bu, eski formatlayıcı ile aynı işlevselliği sunmaya çalışmaktan çok daha temiz. Kullanıcı tarafından sağlanan biçim dizelerini daha güçlü hale getirir.
Taywee

35

%testimden daha iyi performans veriyor format.

Test kodu:

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')")

Sonuç:

> format: 0.470329046249
> %: 0.357107877731

Python 3.5.2

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

Sonuç

> format: 0.5864730989560485
> %: 0.013593495357781649

Python2'ye bakar, fark küçüktür, Python3'te %ise çok daha hızlıdır format.

@Chris Cogdon örnek kodu için teşekkürler.

Düzenleme 1:

Temmuz 2019'da tekrar Python 3.7.2'de test edilmiştir.

Sonuç:

> format: 0.86600608
> %: 0.630180146

Çok fazla fark yok. Sanırım Python yavaş yavaş gelişiyor.

Düzenleme 2:

Birisi yorumda python 3 f-string bahsettikten sonra, python 3.7.2 altında aşağıdaki kod için bir test yaptım:

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

Sonuç:

format: 0.8331376779999999
%: 0.6314778750000001
f-string: 0.766649943

Görünüşe göre f-string hala daha yavaş %ama daha iyi format.


42
Bunun yerine, str.formatdaha fazla işlevsellik sağlar (özellikle tür-özel biçimlendirme '{0:%Y-%m-%d}'.format(datetime.datetime.utcnow())). Performans, tüm işlerin mutlak şartı olamaz. İş için doğru aracı kullanın.
minhee

36
"Erken optimizasyon tüm kötülüğün kökü" ya da Donald Knuth bir zamanlar söyledi ...
Yatharth Agarwal

22
İyi bilinen bir biçimlendirme şemasına bağlı kalmak (vakaların büyük çoğunluğunda ihtiyaç duyduğu ihtiyaçlara uygun olduğu sürece) ve iki kat daha hızlı olan "erken optimizasyon" değildir, ancak mantıklıdır. BTW, %operatör printfbilginin yeniden kullanılmasına izin verir ; sözlük enterpolasyonu prensibin çok basit bir uzantısıdır.
Tobias

5
Aslında tam tersi bir durumda yaşadım. Yeni stil biçimlendirmesi daha hızlıydı. Kullandığınız test kodunu verebilir misiniz?
David Sanders

8
Herhangi bir örnek ya da akıl yürütmeden ciddi bir israf gibi görünüyor, sadece iddia ediyor.
kevr

31

Bugün gördüğüm gibi, üzeri dizeleri biçimlendirme eski yolu %desteklemez Decimal, kutunun ondalık sabit nokta ve kayan nokta aritmetiği, dışarı için Python'un modül.

Örnek (Python 3.3.5 kullanarak):

#!/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))

Çıktı:

0.00000000000000000000000312375239000000009907464850 0.0000000000000000000000000312375239000000000000000000

Kesinlikle çözüm olabilir ama yine de format()yöntemi hemen kullanmayı düşünebilirsiniz .


1
Bunun nedeni muhtemelen yeni stil biçimlendirmesinin str(d)parametreyi genişletmeden önce arama yapmasıdır, oysa eski stil biçimlendirme muhtemelen float(d)önce çağırır .
David Sanders

3
Öyle düşünürdünüz, ama str(d)geri dönüyor "3.12375239e-24", değil"0.00000000000000000000000312375239000000000000000000"
Jack

18

Python'unuz> = 3,6 ise, F-string biçimli hazır bilgi yeni arkadaşınızdır.

Daha basit, temiz ve daha iyi performans.

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)

15

Yan not olarak, günlük kaydıyla yeni stil biçimlendirmesi kullanmak için performans isabeti almanıza gerek yoktur. Sen herhangi bir nesneyi geçirebilir logging.debug, logging.infovb olduğunu uygular __str__sihirli yöntemle. Günlük modülü, ileti nesnenizi (ne olursa olsun) yayması gerektiğine karar verdiğinde, bunu str(message_object)yapmadan önce çağırır . Böylece böyle bir şey yapabilirsiniz:

import logging


class NewStyleLogMessage(object):
    def __init__(self, message, *args, **kwargs):
        self.message = message
        self.args = args
        self.kwargs = kwargs

    def __str__(self):
        args = (i() if callable(i) else i for i in self.args)
        kwargs = dict((k, v() if callable(v) else v) for k, v in self.kwargs.items())

        return self.message.format(*args, **kwargs)

N = NewStyleLogMessage

# Neither one of these messages are formatted (or calculated) until they're
# needed

# Emits "Lazily formatted log entry: 123 foo" in log
logging.debug(N('Lazily formatted log entry: {0} {keyword}', 123, keyword='foo'))


def expensive_func():
    # Do something that takes a long time...
    return 'foo'

# Emits "Expensive log entry: foo" in log
logging.debug(N('Expensive log entry: {keyword}', keyword=expensive_func))

Tüm bunlar Python 3 belgelerinde ( https://docs.python.org/3/howto/logging-cookbook.html#formatting-styles ) açıklanmaktadır. Ancak Python 2.6 ile de çalışacaktır ( https://docs.python.org/2.6/library/logging.html#using-arbitrary-objects-as-messages ).

Bu tekniği kullanmanın avantajlarından biri, biçimlendirme tarzı agnostik olması dışında tembel değerlere, örneğin expensive_funcyukarıdaki fonksiyona izin vermesidir . Bu, Python belgelerinde verilen tavsiyeye daha zarif bir alternatif sunar: https://docs.python.org/2.6/library/logging.html#optimization .


2
Keşke bunu daha fazla oylayabilseydim. formatPerformans isabeti olmadan günlüğe kaydetmeye izin verir - __str__tam olarak loggingtasarlandığı gibi geçersiz kılar - işlev çağrısını, Ndizeleri tanımlamanın standart yollarından bazılarına çok benzeyen tek bir harfe ( ) kısaltır - VE tembelliğe izin verir işlev çağrısı. Teşekkür ederim! +1
CivFan

2
Bu, logging.Formatter(style='{')parametrenin kullanımından farklı mıdır ?
davidA

10

Yardımcı %olabilecek bir durum , normal ifade ifadelerini biçimlendirdiğiniz zamandır. Örneğin,

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

yükseltir IndexError. Bu durumda şunları kullanabilirsiniz:

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

Bu, normal ifadeyi olarak yazmaktan kaçınır '{type_names} [a-z]{{2}}'. Biçim olmadan tek başına kullanılan iki regexiniz olduğunda bu yararlı olabilir, ancak her ikisinin birleşimi biçimlendirilir.


3
Veya sadece kullanın '{type_names} [a-z]{{2}}'.format(type_names='triangle|square'). .format()Zaten yüzde karakteri içeren dizeleri kullanırken söyleme yardımcı olabilir. Elbette. O zaman onlardan kaçmalısın.
Alfe

1
@Alfe Haklısınız ve bu yüzden cevap "One situation where % may help is when you are formatting regex expressions."Özellikle a=r"[a-z]{2}"şu şekilde başlar : İki farklı son ifadede (ör. c1 = b + aVe c2 = a) kullanılacak bir normal ifade yığını olduğunu varsayalım . Varsayın c1edilecek ihtiyaçları format(örneğin ed bçalışma zamanını biçimlendirilmiş olması gerekiyor), ama c2yok. Ardından ihtiyacınız a=r"[a-z]{2}"için c2ve a=r"[a-z]{{2}}"için c1.format(...).
Jorge Leitao

7

3.6 sürümünden beri aşağıdaki gibi fstrings kullanabileceğimizi ekliyorum

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

Hangi vermek

Benim adım John Smith

Her şey dizgeye dönüştürülür

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

Sonuç:

mylist = ['foo', 'bar']

Diğer biçimler yönteminde olduğu gibi işlevi geçebilirsiniz

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

Örneğin vermek

Merhaba, işte tarih: 16/04/2018


4

Python sürümü> = 3.6 için (bkz. PEP 498 )

s1='albha'
s2='beta'

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

#output
'albha      beta'

2

Python 3.6.7 karşılaştırması:

#!/usr/bin/env python
import timeit

def time_it(fn):
    """
    Measure time of execution of a function
    """
    def wrapper(*args, **kwargs):
        t0 = timeit.default_timer()
        fn(*args, **kwargs)
        t1 = timeit.default_timer()
        print("{0:.10f} seconds".format(t1 - t0))
    return wrapper


@time_it
def new_new_format(s):
    print("new_new_format:", f"{s[0]} {s[1]} {s[2]} {s[3]} {s[4]}")


@time_it
def new_format(s):
    print("new_format:", "{0} {1} {2} {3} {4}".format(*s))


@time_it
def old_format(s):
    print("old_format:", "%s %s %s %s %s" % s)


def main():
    samples = (("uno", "dos", "tres", "cuatro", "cinco"), (1,2,3,4,5), (1.1, 2.1, 3.1, 4.1, 5.1), ("uno", 2, 3.14, "cuatro", 5.5),) 
    for s in samples:
        new_new_format(s)
        new_format(s)
        old_format(s)
        print("-----")


if __name__ == '__main__':
    main()

Çıktı:

new_new_format: uno dos tres cuatro cinco
0.0000170280 seconds
new_format: uno dos tres cuatro cinco
0.0000046750 seconds
old_format: uno dos tres cuatro cinco
0.0000034820 seconds
-----
new_new_format: 1 2 3 4 5
0.0000043980 seconds
new_format: 1 2 3 4 5
0.0000062590 seconds
old_format: 1 2 3 4 5
0.0000041730 seconds
-----
new_new_format: 1.1 2.1 3.1 4.1 5.1
0.0000092650 seconds
new_format: 1.1 2.1 3.1 4.1 5.1
0.0000055340 seconds
old_format: 1.1 2.1 3.1 4.1 5.1
0.0000052130 seconds
-----
new_new_format: uno 2 3.14 cuatro 5.5
0.0000053380 seconds
new_format: uno 2 3.14 cuatro 5.5
0.0000047570 seconds
old_format: uno 2 3.14 cuatro 5.5
0.0000045320 seconds
-----

3
Her örneği birkaç kez çalıştırmalısınız, tek bir çalıştırma yanıltıcı olabilir, örneğin işletim sistemi genellikle meşgul olabilir, bu nedenle kodunuzun yürütülmesi gecikir. dokümanlara bakın: docs.python.org/3/library/timeit.html . (güzel avatar, Guybrush!)
jake77

1

Ancak bir şey, kıvırcık parantezleri iç içe geçirdiyseniz, format için çalışmayacak, ancak %işe yarayacaktır.

Misal:

>>> '{{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}'
>>> 

2
bunu yapabilirsin, ama katılıyorum '{{{0}, {1}}}'. formatında (1, 2)
Sylvan LE DEUNFF

İç içe anahtar kelime kıvırcık parantez çalışır ve güzel.
CivFan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.