ट्रैक
/
Python
Python
/
सिलेबस
/
स्ट्रिंग फॉर्मेटिंग
स्

स्ट्रिंग फॉर्मेटिंग में Python

1 अभ्यास

स्ट्रिंग फॉर्मेटिंग के बारे में

Python में स्ट्रिंग फॉर्मेटिंग

स्ट्रिंग फॉर्मेटिंग एक ऐसी प्रक्रिया है जिसमें वैल्यू को स्ट्रिंग में बदला जाता है और फिर उन्हें किसी स्ट्रिंग टेम्पलेट में डाला जाता है। Zen of Python कहता है कि Python में किसी काम को करने का "एक ही स्पष्ट तरीका" होना चाहिए। लेकिन स्ट्रिंग फॉर्मेटिंग की बात आते ही मामला थोड़ा... कम ज़ेन हो जाता है।

यह जानकर आश्चर्य हो सकता है कि Python में स्ट्रिंग फॉर्मेटिंग करने के चार मुख्य तरीके हैं, और हर तरीका किसी अलग स्थिति के लिए है। इसकी एक वजह Python का लंबा इतिहास है, और दूसरी वजह इंटरनेशनलाइज़ेशन या इनपुट सैनिटाइज़ेशन जैसी ज़रूरतें हैं। हम स्ट्रिंग फॉर्मेटिंग के टूलबॉक्स में सबसे नए जुड़े तरीकों से शुरू करेंगे और पीछे की ओर चलते हुए "पुराने स्टाइल" या "printf() स्टाइल" स्ट्रिंग फॉर्मेटिंग तक पहुँचेंगे।

लिटरल स्ट्रिंग इंटरपोलेशन: f-string

Python 3.6 में पेश किए गए f-string (यानी "formatted strings" का छोटा रूप) या लिटरल स्ट्रिंग इंटरपोलेशन, एक्सप्रेशन और स्ट्रिंग को जल्दी और कुशलता से मूल्यांकित करके str टाइप में बदलने (और फॉर्मेट करने) का तरीका हैं। इसके लिए कोट्स से पहले f (या F) प्रीफिक्स लगाया जाता है (_जैसे: f'{object}')।

f-string हर उस स्ट्रिंग के साथ इस्तेमाल की जा सकती है जो किसी भी तरह के कोट्स में लिखी गई हो, जैसे सिंगल-लाइन (' या ") और मल्टी-लाइन (''' या """)। {} के अंदर रखे गए वेरिएबल, एक्सप्रेशन या किसी भी अन्य टाइप की वैल्यू का पहले मूल्यांकन किया जाता है, फिर उन्हें str में बदला जाता है, और अंत में कर्ली ब्रैकेट के बाहर की किसी भी str के साथ जोड़ दिया जाता है।

इस उदाहरण में हम एक वाक्य में दो वेरिएबल की वैल्यू डालते हैं (एक str और एक float):

>>> name = 'eighth'
>>> value = 1/8

# The f-string, using the two values.
# The .2f format code truncates, so the value displays as 0.12.
>>> f'An {name} is approximately {value:.2f}.'
'An eighth is approximately 0.12.'

जो एक्सप्रेशन मूल्यांकित किए जाते हैं, वे लगभग कुछ भी हो सकते हैं। मूल्यांकित की जा सकने वाली संभावनाओं में से कुछ: str, संख्याएँ, वेरिएबल, अंकगणितीय एक्सप्रेशन, शर्त वाले एक्सप्रेशन, बिल्ट-इन टाइप, स्लाइस, फंक्शन, lambda, कॉम्प्रिहेंशन, या ऐसे कोई भी ऑब्जेक्ट जिनमें __str__ या __repr__ मेथड परिभाषित हों।

अब सरल से जटिल की ओर बढ़ते हैं:

वेरिएबल डालना: f-string का सबसे सरल उपयोग यह है कि आप वेरिएबल को सीधे स्ट्रिंग के अंदर रख दें।

# Assigning a variable.
>>> name = "World"

# Inserting that variable.
>>> f'Hello, {name}!'
'Hello, World!'

{} के अंदर एक्सप्रेशन: कर्ली ब्रैकेट के अंदर कोई भी मान्य Python एक्सप्रेशन मूल्यांकित किया जा सकता है। ध्यान दीजिए कि सिंगल-कोटेड f-string के अंदर डबल कोट्स इस्तेमाल करने पर (या इसके उलट) एस्केप सीक्वेंस की ज़रूरत नहीं पड़ती:

# A dictionary of key:value pairs.
>>> waves = {'water': 1, 'light': 3, 'sound': 5}

# Inserting the whole dict.
>>> f'Wave ranks: {waves}'
"Wave ranks: {'water': 1, 'light': 3, 'sound': 5}"

# An expression can be evaluated inline:
>>> f"Tenfold the value of 'light' is {waves['light'] * 10}."
"Tenfold the value of 'light' is 30."

# A method call can also be evaluated inline:
>>> f'{"hello world!".title()} is a classic greeting.'
'Hello World! is a classic greeting.'

# An f-string can be nested inside another f-string:
>>> f"{f'hello world!'.title()} is a classic greeting."
'Hello World! is a classic greeting.'

आउटपुट फॉर्मेटिंग: फॉर्मेट स्पेसिफिकेशन मिनी-लैंग्वेज की मदद से संरेखण, संख्यात्मक परिशुद्धता और बहुत कुछ नियंत्रित किया जा सकता है। फॉर्मेट स्पेसिफिकेशन वैल्यू के बाद आता है, और दोनों के बीच : लगाया जाता है।

# Right-align a value to ten characters, and round it to 3 decimal places.
>>> value = 1 / 7
>>> f'One seventh is {value:10.3f}.'
'One seventh is      0.143.'

# A format specification can be set using variables as well.
>>> padding = 10
>>> precision = 3
>>> f'One seventh is {value:{padding}.{precision}f}.'
'One seventh is      0.143.'

सब कुछ एक साथ: वेरिएबल, एक्सप्रेशन, फंक्शन कॉल और आउटपुट फॉर्मेटिंग:

>>> precision = 3
>>> f"{30e8 * 111_000:6.{precision}e}"
'3.330e+14'

>>> verb = 'meet'
>>> the_end = ['end', 'of', 'transmission']
>>> f'"Have a {"NICE".lower()} day, I will {verb} you after {30e8 * 111_000:6.{precision}e} light-years."{the_end}'
'"Have a nice day, I will meet you after 3.330e+14 light-years."[\'end\', \'of\', \'transmission\']'

# Did you notice the escaped single-quotes in the previous example?
# Using double quotes instead of single quotes for the f-string means the list's single-quoted strings print cleanly.
>>> f"Have a nice day. {the_end}"
"Have a nice day. ['end', 'of', 'transmission']"

यहाँ दो मुख्य सीमाएँ हैं जिनका ध्यान रखना ज़रूरी है। f-string के एक्सप्रेशन खाली नहीं हो सकते। इसके अलावा, Python 3.12 से पहले इनमें कमेंट भी नहीं हो सकते थे।

>>> f"An empty expression will error: {}"
SyntaxError: f-string: empty expression not allowed

>>> word = 'word'
>>> f"""A comment in a triple quoted f-string: {
    word # I chose a nice variable
}"""
'A comment in a triple quoted f-string: word'
Caution

इंटरनेशनलाइज़ेशन (I18N) और लोकलाइज़ेशन (L10N) के लिए स्ट्रिंग इंटरपोलेशन का इस्तेमाल GNU gettext API के साथ नहीं किया जा सकता। इसलिए ऐसे अनुवाद कार्यों में जहाँ स्ट्रिंग को लपेटना हो, f-string की जगह नीचे बताई गई string.Template क्लास या str.format() मेथड इस्तेमाल करने की सलाह दी जाती है।

यह भी ध्यान रखें कि f-string के ब्रैकेट {} के अंदर एक्सप्रेशन इस्तेमाल करना eval() या exec() इस्तेमाल करने जैसा है, इसलिए यह बहुत सुरक्षित नहीं है और इसे यूज़र इनपुट के साथ कभी नहीं इस्तेमाल करना चाहिए।

str.format() मेथड

str.format() मेथड स्ट्रिंग के अंदर मौजूद प्लेसहोल्डर को उन वैल्यू से बदल देता है जो फंक्शन को आर्गुमेंट के रूप में दी जाती हैं। प्लेसहोल्डर को नाम ({price}), संख्या ({0} या इंडेक्स) या खाली (पोज़िशनल) प्लेसहोल्डर {} से पहचाना जाता है।

उदाहरण के लिए:

# A named placeholder and a positional placeholder.
>>> 'My text: {placeholder_1} and {}.'.format(12, placeholder_1='named placeholder')
'My text: named placeholder and 12.'

f-string की तरह ही Python का str.format() भी ढेरों मिनी लैंग्वेज फॉर्मेट स्पेसिफायर सपोर्ट करता है, जिनकी मदद से टेक्स्ट को संरेखित किया जा सकता है, फ्लोट को छोटा किया जा सकता है, और बहुत कुछ किया जा सकता है।

पूरा फॉर्मेटिंग स्पेसिफायर पैटर्न इस तरह होता है: {[<name>][!<conversion>][:<format_specifier>]}:

  • <name> एक नाम वाला प्लेसहोल्डर, कोई संख्या, या खाली हो सकता है।
  • !<conversion> वैकल्पिक है और इन तीन रूपांतरणों में से एक होना चाहिए: str() के लिए !s, repr() के लिए !r, या ascii() के लिए !a। डिफॉल्ट रूप से str() इस्तेमाल होता है।
  • :<format_specifier> वैकल्पिक है और यह तय करता है कि वैल्यू कैसे प्रदर्शित होगी। उपलब्ध विकल्पों के बारे में ज़्यादा जानकारी यहाँ मिलेगी।

एक डायक्रिटिक अक्षर के लिए रूपांतरण का उदाहरण:

# Fills in the object at index zero, converted to a string.
>>> 'An e with an umlaut: {0!s}'.format('ë')
'An e with an umlaut: ë'


# Fills in the object at index zero, converted to a repr.
>>> 'An e with an umlaut (object representation): {0!r}'.format('ë')
"An e with an umlaut (object representation): 'ë'"


# Fills in the object at index zero, converted to ASCII.
>>> 'An e with an umlaut converted into ASCII: {0!a}'.format('ë')
"An e with an umlaut converted into ASCII: '\xeb'"


# Fills in the object in the first position,
# then fills in the object in the second position formatted as a repr.
>>> 'She said her name is not {} but {!r}.'.format('Chloe', 'Zoë')
"She said her name is not Chloe but 'Zoë'."

आम फॉर्मेट स्पेसिफायर के उदाहरण:

# Integer and binary/hex representations of the same number.
>>> my_num = 42
>>> f"{my_num} in binary is {my_num:b}. In hex, it is {my_num:x}"
"42 in binary is 101010. In hex, it is 2a"

# Alignment: left (<), right (>), and center (^) using up to ten characters total.
>>> f"[{"left":<10}] [{"right":>10}] [{"center":^10}]"
"[left      ] [     right] [  center  ]"

# Float precision and scientific notation (up to three decimal places).
>>> pi = 3.141592653589793
>>> f"Fixed: {pi:.3}  Scientific: {pi:.3e}"
"Fixed: 3.142  Scientific: 3.142e+00"

# Thousands separator and percentage.
>>> balance = 1000
>>> rate = 0.0225
>>> f"Balance: ${balance:,.0f}  Interest rate: {rate:.1%}"
"Balance: $1,000  Interest rate: 2.2%"

# Putting it all together:
>>> items = [("Widget", 1250, 9.991), ("Gadget", 37, 24.503), ("Doohickey", 4, 149.002)]
>>> header = f"{"Item":<12} {"Qty":>6} {"Price":>9}"
>>> print(header)
Item            Qty     Price
>>> for name, qty, price in items:
...     print(f"{name:<12} {qty:>6} {price:>9.2f}")
Widget         1250      9.99
Gadget           37     24.50
Doohickey         4    149.00

और भी उदाहरण इस डॉक्युमेंटेशन के अंत में दिखाए गए हैं।

% फॉर्मेटिंग, या printf() स्टाइल फॉर्मेटिंग

Python में स्ट्रिंग फॉर्मेटिंग का सबसे पुराना तरीका फॉर्मेटिंग के लिए % ऑपरेटर का इस्तेमाल है। यह C भाषा से आया है और इसमें पोज़िशनल आर्गुमेंट की मदद से str बनाया जा सकता है।

f-string और str.format() दोनों ने इस तरीके की जगह ले ली है, इसीलिए % फॉर्मेटिंग को "पुराना स्टाइल" कहा जाता है। यह अब भी Python 2 और/या पुराने कोड में मिल जाता है। Python 3.x में यह तरीका काम तो करता है, पर आमतौर पर % फॉर्मेटिंग से बचा जाता है, क्योंकि इसमें गलती होने की गुंजाइश ज़्यादा है, यह कम कुशल है, इसमें विकल्प कम हैं, और प्लेसहोल्डर तथा आर्गुमेंट में मेल न बैठने पर एक्सेप्शन भी आ सकता है। % ऑपरेटर का इस्तेमाल printf() जैसा ही है, इसलिए इसे कभी-कभी printf फॉर्मेटिंग भी कहा जाता है।

# Assigning a variable.
>>> name = "Anna-conda"

# Building a string using %.
>>> "The snake's name is %s." % name
"The snake's name is Anna-conda."

ऊपर के उदाहरण में % ऑपरेटर रनटाइम पर प्लेसहोल्डर %s की जगह वेरिएबल name की वैल्यू रख देता है। अगर आपको एक स्ट्रिंग में कई वेरिएबल जोड़ने हैं, तो % के बाद एक टपल देना होगा जिसमें हर प्लेसहोल्डर के लिए एक ऑब्जेक्ट हो:

# Assigning variables.
>>> name = "Billy the Kid"
>>> fruit = "grapes"

# Building a string using %.
>>> "Surprisingly, %s's favorite snack was %s." %(name, fruit)
"Surprisingly, Billy the Kid's favorite snack was grapes."

टेम्पलेट स्ट्रिंग

string.Template() (इसे Python 3.14 की t-strings से नहीं मिलाइए) string मॉड्यूल की एक क्लास है (बिल्ट-इन str टाइप से अलग)। यह Python की स्टैंडर्ड लाइब्रेरी का हिस्सा है, पर इस्तेमाल करने के लिए इसे इम्पोर्ट करना पड़ता है। टेम्पलेट स्ट्रिंग $ आधारित प्रतिस्थापन सपोर्ट करती हैं और यहाँ बताए गए बाकी विकल्पों की तुलना में कहीं ज़्यादा सरल और कम सक्षम हैं। फिर भी, जटिल इंटरनेशनलाइज़ेशन या बाहर से आने वाले इनपुट को साफ़ करने के लिए ये बहुत काम की हो सकती हैं।

string.Template को उस यूज़र इनपुट के लिए ज़्यादा सुरक्षित माना जाता है जिस पर भरोसा नहीं किया जा सकता, क्योंकि यह मनमाने एक्सप्रेशन मूल्यांकित करने और ऑब्जेक्ट एट्रिब्यूट तक पहुँचने से रोकता है। इससे फॉर्मेट-स्ट्रिंग इंजेक्शन हमलों का खतरा कम हो जाता है।

>>> from string import Template

>>> name = "Anna-Conda"

# Creating a Template with placeholder text.
>>> template_string = Template("The snake called `$snake_name` has escaped!")

# Calling .substitute() to replace the placeholder with a value.
>>> template_string.substitute(snake_name=name)
'The snake called `Anna-Conda` has escaped!'

string.Template के बारे में ज़्यादा जानकारी Python के डॉक्युमेंटेशन में मिल सकती है।

आप कौन-सा फॉर्मेटिंग तरीका चुनें?

इतने सारे विकल्पों और मिनी-लैंग्वेज के बीच, Python की स्ट्रिंग फॉर्मेट करते समय आप तय कैसे करें कि किसका इस्तेमाल करें? यहाँ कुछ छोटे दिशानिर्देश दिए गए हैं:

  1. f-string सबसे नई है और पढ़ने में सबसे आसान। अगर आपको इंटरनेशनलाइज़ेशन की ज़रूरत नहीं है, तो Python 3.6+ के लिए यही पसंदीदा तरीका होना चाहिए।

  2. str.format() बहुमुखी और शक्तिशाली है, और यह gnu gettext तथा Python के ज़्यादातर वर्शन के साथ संगत है।

  3. अगर आपको सादगी, सुरक्षा और/या गहन इंटरनेशनलाइज़ेशन चाहिए, तो string.Template() का इस्तेमाल यूज़र से आने वाले इनपुट संभालते समय जोखिम कम करने के लिए और अनुवाद की स्ट्रिंग को लपेटने के लिए किया जा सकता है।

  4. नए कोड के लिए % ऑपरेटर को आमतौर पर पुराना माना जाता है, हालाँकि यह आधुनिक Python में अब भी काम करता है। इसका इस्तेमाल ज़्यादातर पुराने कोडबेस के साथ संगतता के लिए ही करना चाहिए। बाकी तरीकों की तुलना में % फॉर्मेटिंग में गलती होने की गुंजाइश ज़्यादा है (और सुविधाएँ कम हैं), और इससे ऐसे अक्षर प्रदर्शित करने में दिक्कतें आ सकती हैं जो ASCII में नहीं हैं। अगर आप इसे इस्तेमाल करना चाहते हैं, तो सपोर्ट की जानकारी अपने खास Python डिस्ट्रिब्यूशन में देख लीजिए।

अगर आप और आगे जाना चाहते हैं, तो all about formatting और Python String Formatting Best Practices अच्छी शुरुआत हैं।

GitHub के ज़रिए संपादित करें यह लिंक नई विंडो या टैब में खुलता है।