F-satrlarini baholashni qoldirib berishi mumkinmi?

Shablonlar satrlarini ba'zi fayllarni yaratish uchun foydalanayapman va bu maqsad uchun yangi f-stringsning uzviyligini yaxshi ko'raman.

Ilgari bunday qilaman:

template_a = "The current name is {name}"
names = ["foo", "bar"]
for name in names:
    print (template_a.format(**locals()))

Endi buni qilishim mumkin:

names = ["foo", "bar"]
for name in names:
    print (f"The current name is {name}")

Ammo, ba'zan shablonni boshqa joyda aniqlab olish mantiqiy bo'ladi - kodning yuqorisida yoki biror fayldan yoki biror narsadan olingan. Bu shabloni formatlash belgilariga ega bo'lgan statik simvol degan ma'noni anglatadi. Tarjimonga mag'lubiyatni yangi f-string deb izohlashni aytadigan satrga biror narsa to'g'ri kelishi kerak edi, lekin bunday narsaning mavjudligini bilmayman.

.format (** locals ()) chaqiruvidan foydalanishni oldini olish uchun mag'lubiyatga olib keladigan biror f-string deb talqin qilish mumkinmi?

Ideal:

template_a = f"The current name is {name}"
names = ["foo", "bar"]
for name in names:
    print (template_a)

Istagan chiqishi:

The current name is foo
The current name is bar

Haqiqiy chiqishi:

The current name is {name}
The current name is {name}

Tahrirlash:

Ideal 2:

template.txt tarkiblari Joriy nom {ism} ). magic_fstring_function - bu men tushunmagan qism keladi.

template_a = magic_fstring_function(open('template.txt').read())
names = ["foo", "bar"]
for name in names:
    print (template_a)

Desired Output (faylni ikki marta o'qimasdan):

The current name is foo
The current name is bar

Haqiqiy chiqishi:

The current name is {name}
The current name is {name}
29
Buni f string bilan qilolmaysiz. Agar f mag'lubiyati ma'lumot emas va bu, albatta, mag'lubiyat emas; bu kod. (Kodni disk moduli bilan tekshiring.) Keyinchalik kodni baholashni xohlasangiz, siz funktsiyani ishlatasiz.
qo'shib qo'ydi muallif kindall, manba
FYI, PEP 501 birinchi idealga yaqin xususiyatni taklif qildi, ammo hozirda "f-strings" bilan keyingi tajribaga ega bo'lgan ertelenmiş ".
qo'shib qo'ydi muallif jwodder, manba

6 javoblar

F-mag'lubiyat kodi .format (** nomlari) o'rniga f o'rniga formatlashtirilgan formatdagi simni yaratishning yanada ixcham usulidir. Agar siz mag'lubiyatni darhol baholashni istamasangiz, uni f-string qilmang. Uni odatiy bir mag'lubiyatga aylantirib saqlang va undan keyin siz kiritgan interpolatsiyani amalga oshirish uchun undan keyin format deb chaqiring.

Albatta, eval bilan muqobil mavjud.

template.txt:

Joriy ism - {name} "

Kod:

>>> template_a = open('template.txt').read()
>>> names = 'foo', 'bar'
>>> for name in names:
...     print(eval(template_a))
...
The current name is foo
The current name is bar

Lekin keyinchalik amalga oshirgan barcha narsalar str.format kodini eval bilan almashtirishdir. Faqat formati chaqiruvi bilan muntazam satrlardan foydalaning.

9
qo'shib qo'ydi
@philh Men faqatgina .format f-mag'lubiyatiga mos kelmagan misolga duch keldim deb o'ylayman. Bu sizni qo'llab-quvvatlashi mumkin: DNA = "TATTCGCGGAAAATATTTTGA"; fragment = f "{DNK [2: 8]}"; failed_fragment = "{DNK [2: 8]}" formati (** mahalliy ()) . failed_fragment yaratish uchun urinish TypeError: string ko'rsatkichlari tamsayılar bo'lishi kerak .
qo'shib qo'ydi muallif bli, manba
Sizning kodingiz parchasida hech qanday afzalliklarni ko'rmayapman. Demak, har doim template.txt faylida Joriy ism {name}} ni yozishingiz va keyin print (template_a.format (name = name )) (yoki .format (** locals ()) ). Kod taxminan 10 belgidan oshiq bo'lsa-da, eval tufayli yuzaga keladigan har qanday xavfsizlik muammolarini keltirib chiqarmaydi.
qo'shib qo'ydi muallif Bakuriu, manba
@Bakuriu - Ha; eval bizga f "{name}" yozishni va istalgancha name ni baholashni kechiktirishga imkon beradi, desam, u past shunchaki oddiy shablonini yaratish va undan keyin format ni chaqirish kerak.
qo'shib qo'ydi muallif TigerhawkT3, manba
"F-string - fformat (** nomlar) ni f bilan o'zgartiradigan formatli simni yaratishning oddiy usulidir". Aksincha, ular turli xil sintaksisdan foydalanadilar. Menda yaqinda tekshirish uchun etarli python3 yo'q, lekin, masalan, "{a + b}" ishlayotganligiga ishonaman, "{a + b}" formati (a = a, b = b) KeyError . .format() ko'p jihatlarda yaxshi bo'lishi mumkin, ammo bu tomchi o'zgarish emas.
qo'shib qo'ydi muallif philh, manba

Mana, to'liq "Ideal 2".

F-stringni ishlatmaslik f-string emas. Lekin bu so'ralgan. Sintaksis aniq ko'rsatilgan. Biz baholash vositasidan foydalanmasligimiz sababli hech qanday xavfsizlik boshlig'i yo'q.

Kichik bir sinfdan foydalanadi va __ str __ amalga oshiriladi, u avtomatik ravishda chop etish orqali chaqiriladi. Sinfning cheklangan doirasidan qochish uchun inspect moduli yordamida bir kvadratni yuqoriga siljitish va qidiruvchiga kira oladigan parametrlarga qarang.

import inspect

class magic_fstring_function:
    def __init__(self, payload):
        self.payload = payload
    def __str__(self):
        vars = inspect.currentframe().f_back.f_globals.copy()
        vars.update(inspect.currentframe().f_back.f_locals)
        return self.payload.format(**vars)

template = "The current name is {name}"

template_a = magic_fstring_function(template)

# use it inside a function to demonstrate it gets the scoping right
def new_scope():
    names = ["foo", "bar"]
    for name in names:
        print(template_a)

new_scope()
# The current name is foo
# The current name is bar
6
qo'shib qo'ydi
Shablon oddiy o'zgaruvchan ismga qaraganda murakkabroq narsa bo'lsa, bu ishlamaydi. Masalan: template = "Ismning boshlanishi {name [: 4]}" (-> TypeError: string ko'rsatkichlari tamsayılar bo'lishi kerak )
qo'shib qo'ydi muallif bli, manba
@JDAnders Iltimos, aytmoqchi bo'lgan eng so'nggi va eng katta versiyani ko'rib chiqing: "Ideal 2" ni vergulga kiritadi.
qo'shib qo'ydi muallif Paul Panzer, manba
@bli Qizig'i shundaki, str.format ning cheklovi kabi ko'rinadi. Men f-strings faqatgina str.format (** locals (), globals ())) kabi narsalar uchun sintaktik shakar, deb o'ylar edim.
qo'shib qo'ydi muallif Paul Panzer, manba
Bu shablonni boshqa joylarda belgilashga imkon beradi, lekin mag'lubiyat sifatida emas. Shablonlarni qilishning bir usuli {format} belgilar bilan to'la fayl. Ushbu echim shabloni open ("file") dan keladigan holatga moslashtirilishi mumkinmi? (O'qiyapsizmi() (har doim faylni har doim qayta o'qimasdan umid qilamanki)? Men savolni tushuntirish uchun tahrir qilaman.
qo'shib qo'ydi muallif JDAnders, manba
Men buni bu javob sifatida qabul qilaman, lekin juda aqlli bo'lgani uchun uni kodda qo'llayman deb o'ylamayman. Ehtimol, hech qachon :). Ehtimol, python aholisi uni PEP 501 amalga oshirish uchun ishlatishi mumkin. Agar mening savollarim "bu stsenariyni qanday bajarishim kerak bo'lsa" javob "faqat .format() funktsiyasidan foydalanishni davom ettiradi va PEP 501ni hal qilishini kutib turadi." Nima qilish kerakligini bilib olganingiz uchun tashakkur, @PaulPanzer
qo'shib qo'ydi muallif JDAnders, manba

Bu shabloni

da formatlash belgilariga ega statik simvol degan ma'noni anglatadi

Ha, shuning uchun bizda nusxalash ob'ektlari va .format harflari mavjud, shuning uchun biz xohlagan joylarimizni formati deb chaqirishimiz mumkin.

Tarjimonga mag'lubiyatni yangi f-string deb izohlash uchun satrga biror narsa to'g'ri keladi.

Bu f/F prefiksi. Agar siz uni funksiyaga ulashingiz va qo'ng'iroq vaqtida baholashni kechiktirishingiz mumkin, lekin, albatta, qo'shimcha xarajatlar kelib chiqishi mumkin:

template_a = lambda: f"The current name is {name}"
names = ["foo", "bar"]
for name in names:
    print (template_a())

Qanday bosim chiqaradi:

The current name is foo
The current name is bar

ammo o'zingizni noto'g'ri his qilyapsiz va siz faqat sizning almashtirishlaringizdagi global nomdagi nomlarni ko'rib chiqishingiz mumkin. Mahalliy nomlarni talab qiladigan vaziyatda uni ishlatishga urinib, mag'lubiyatga dalil sifatida o'tmasa (u butunlay mag'lubiyatga uchratsa) muvaffaqiyatsizlikka uchraydi.

.format (** locals ()) chaqiruvidan foydalanishni oldini olish uchun mag'lubiyatga olib keladigan biron bir usul bormi?

Funktsiyadan tashqari (cheklashlar kiritilgan), shuning uchun ham .format bilan yopishishi mumkin.

3
qo'shib qo'ydi
@PaulPanzer siz savolni tahrirlash va uni qayta kiritishni xohlaysizmi? Javobni o'chirib tashlamasman. Bu OSh davosi uchun muqobil variant bo'lib, all holatlarida yashashga yaroqli muqobil emas, bu hiyla-nayrang.
qo'shib qo'ydi muallif Jim Fasarakis Hilliard, manba
Qiziqarli, men xuddi o'sha parchani yozib qo'ydim. Lekin cheklovlarni cheklash sababli uni rad etdi. (Funktsiya uchun forintni o'rashga harakat qiling.)
qo'shib qo'ydi muallif Paul Panzer, manba
Yo'q, yaxshi, uni saqlang. Men yangi echim bilan juda xursandman. Ammo sizning cheklashlaringizdan xabardor bo'lsangiz, bu sizning hayotingiz uchun foydali ekanligini tushunib etaman. Balki posting uchun bir oz ogohlantirish qo'sha olasizmi? Shuning uchun hech kim bu noto'g'ri foydalanib, oyog'ini ololmaydi?
qo'shib qo'ydi muallif Paul Panzer, manba

Yoki faqat f-stringsdan foydalanmang, balki formatni:

fun = "The curent name is {name}".format
names = ["foo", "bar"]
for name in names:
    print(fun(name=name))

Nomlarsiz versiyada:

fun = "The curent name is {}".format
names = ["foo", "bar"]
for name in names:
    print(fun(name))
3
qo'shib qo'ydi
Bu barcha hollarda ishlamaydi. Misol: fun = "{DNK [2: 8]}" formati; DNK = "TATTGGGGGAAAATATTTTGA"; qiziqarli (DNK = DNK) . -> TypeError: magistral ko'rsatkichlari butun son bo'lishi kerak
qo'shib qo'ydi muallif bli, manba
Lekin bu oddiy ishlatishda ham ishlamaydi, iltimos, javobni ko'rib chiqing stackoverflow.com/questions/14072810/…
qo'shib qo'ydi muallif msztolcman, manba

.Formatdan foydalanish bu savolga to'g'ri javob emas. Python f-strings str.format() shablonlaridan juda farq qiladi ... ular kod yoki boshqa qimmat operatsiyalarni o'z ichiga olishi mumkin - shuning uchun kechiktirish kerak.

Ertelenen yozishchining misoli. Bu logging.getLoggerning odatiy boshlanishidan foydalanadi, lekin keyin f-mag'lubini sharhlaydigan yangi funktsiyalarni faqat log darajasi to'g'ri bo'lsa qo'shimchalar.

log = logging.getLogger(__name__)

def __deferred_flog(log, fstr, level, *args):
    if log.isEnabledFor(level):
        import inspect
        frame = inspect.currentframe().f_back.f_back
        try:
            fstr = 'f"' + fstr + '"'
            log.log(level, eval(fstr, frame.f_globals, frame.f_locals))
        finally:
            del frame
log.fdebug = lambda fstr, *args: __deferred_flog(log, fstr, logging.DEBUG, *args)
log.finfo = lambda fstr, *args: __deferred_flog(log, fstr, logging.INFO, *args)

Bu kabi narsalarni qilishning afzalligi bor: log.fdebug ("{obj.dump ()") .... disk raskadrovka yoqilmagan bo'lsa, ob'ektni tashlamasdan.

0
qo'shib qo'ydi

F-satrlarini ishlatadigan taklif. Sizning baholaringizni baholang mantiqiy daraja bo'lib, shablonning yuzaga kelishi va generator sifatida o'tkazilishi. Siz tanlagan har qanday nuqtada, f-stringsdan foydalanib, uni ochib qo'yishingiz mumkin

In [46]: names = (i for i in ('The CIO, Reed', 'The homeless guy, Arnot', 'The security guard Spencer'))

In [47]: po = (f'Strangely, {next(names)} has a nice {i}' for i in (" nice house", " fast car", " big boat"))

In [48]: while True:  
...:     try:  
...:         print(next(po))  
...:     except StopIteration:  
...:         break  
...:       
Strangely, The CIO, Reed has a nice  nice house  
Strangely, The homeless guy, Arnot has a nice  fast car  
Strangely, The security guard Spencer has a nice  big boat  
0
qo'shib qo'ydi
Python
Python
372 ishtirokchilar

Bu guruh python dasturlash tilini muhokama qilish uchun. Iltimos, o'zingizni hurmat qiling va faqat dasturlash bo'yicha yozing. Botlar mavzusini @botlarhaqida guruhida muhokama qling! FAQ: @PyFAQ Offtopic: @python_uz_offtopic

Python offtopic group !
Python offtopic group !
150 ishtirokchilar

@python_uz gruppasining offtop gruppasi. offtop bo'lsa ham reklama mumkin emas ) Boshqa dasturlash tiliga oid gruppalar @languages_programming