2013-10-23 6 views
8

मैं आमतौर पर निम्नलिखित पैटर्न (this question में उल्लेख किया) का उपयोग करें:संक्षिप्त रूप (..., ** स्थानीय लोगों())

a=1 
s= "{a}".format(**locals()) 

मुझे लगता है कि यह एक शानदार तरीका आसानी से पढ़ने योग्य लिखने के लिए है कोड।

a="1" 
b="2" 
c="{a}+{b}".format(**locals()) 
d="{c} is a sum".format(**locals()) 
#d=="1+2 is a sum" 

बहुत जल्द, कोड X.format(**locals()) साथ सताया जाता है:

कभी कभी यह जटिल तार के सृजन "modularize" से "श्रृंखला" स्ट्रिंग स्वरूपों के लिए उपयोगी है, क्रम में। इस समस्या को हल करने के लिए, मैं एक लैम्ब्डा बनाने की कोशिश की:

f= lambda x: x.format(**locals()) 
a="1" 
b="2" 
c= f("{a}+{b}") 
d= f("{c} is a sum") 

लेकिन यह एक KeyError फेंकता है, के बाद से locals() लैम्ब्डा के स्थानीय लोगों के हैं।

मैं भी केवल पिछले स्ट्रिंग पर प्रारूप को लागू करने की कोशिश की:

a="1" 
b="2" 
c="{a}+{b}" 
d="{c} is a sum".format(**locals()) 
#d=="{a}+{b} is a sum" 

लेकिन यह काम नहीं करता है, के बाद से अजगर केवल एक बार स्वरूपों।

def my_format(string, vars): 
    f= string.format(**vars) 
    return f if f==string else my_format(f, vars) 

लेकिन मैं सोच रहा हूँ: वहाँ यह करने के लिए एक बेहतर तरीका है अब, मैं एक समारोह है कि बार-बार स्वरूपों जब तक यहां और भी कुछ भी नहीं करना लिख ​​सकता है?

उत्तर

4

f = lambda x, l=locals(): x.format(**l) काम करने के लिए ...

प्रकट होता है और अगर आप एक संस्करण है कि एक छोटे से अधिक सर्वव्यापी (और शायद बहुत धीमी) चाहता था:

fg = lambda x, l=locals(), g=globals(): x.format(**dict(g.items() + l.items())) 

में प्रतीकों मिलेगा या तो स्थानीय या ग्लोबल्स।

+0

आप शायद स्थानीय लोगों को ग्लोबल्स को ओवरराइड करना चाहते हैं। वर्तमान में, आपके पास यह दूसरा रास्ता है, क्योंकि बाद में तर्क जीतने के लिए तर्क। – Collin

+0

अच्छा बिंदु ... मैं वह परिवर्तन करूंगा। –

0

यह एक एक लाइनर नहीं है, लेकिन यह काम करता है:

fmt = lambda s, l=locals(): fmt(s.format(**l), l=l) if '{' in s else s 
2

आप केवल अंदर यह करने के लिए की जरूरत है:

def fmt(s, l=locals()): 
    while '{' in s: 
     s = s.format(**l) 
    return s 

a="1" 
b="2" 
c="{a}+{b}" 
d="{c} is a sum" 

print fmt(d) # 1+2 is a sum 

यहाँ एक एक पंक्ति (और थोड़ा कम कुशल) पुनरावर्ती संस्करण है एक स्थानीय शॉर्टकट के रूप में समारोह गुंजाइश, निम्नलिखित काम करेगा:

def formatter(fmt, loc=locals()): 
    return fmt.format(**loc) 

हालांकि, इस मूल्य सेवानिवृत्त बाध्य होगा फ़ंक्शन घोषणा के समय locals() द्वारा निष्पादन के बजाए, इसलिए इसे मूल्य परिवर्तन के रूप में अपडेट नहीं किया जाएगा, और न ही किसी अन्य दायरे से बुलाए जाने पर यह उपयोगी होगा।

आप के लिए बुला विधि के locals, आप कॉल स्टैक (http://docs.python.org/2/library/inspect.html)

import inspect 

def formatter(fmt): 
    parent = inspect.stack()[1][0] # 1 = the previous frame context 
            # 0 = the frame object 
    return fmt.format(**parent.f_locals) 

ध्यान दें कि यह है कि CPython नहीं हैं अजगर के कार्यान्वयन के लिए काम नहीं कर सकता inspect करने की जरूरत है पहुँच प्राप्त करना चाहते हैं।

अब आप कर सकते हैं:

a = "1" 
b = "2" 
c = formatter("{a}+{b}") 
d = formatter("{c} is a sum") 
+0

असल में, यह कभी-कभी सच है, लेकिन हमेशा नहीं ... ऐसा लगता है कि स्थानीय() वास्तव में 'स्थानीय' के ताना मूल्य पर एक सूचक लौटाते हैं, जो बदलता प्रतीत होता है। आप निम्नलिखित प्रयोग कर सकते हैं: 'f = स्थानीय(); एक्स = 1; जी = स्थानीय(); एफ == जी', जो सच होगा, भले ही आपने एफ और जी के बीच एक स्थानीय मान संशोधित किया हो। इसके अलावा: 'डीफ़ एफएन (एक्स, एल = स्थानीय()): प्रिंट एल [एक्स]; एक्स = 2; fn ('एक्स'); एक्स = 3; एफएन ('एक्स') '2 प्रिंट करेगा, फिर 3. ऐसा लगता है कि यह कभी-कभी सच होना चाहिए, इसलिए यह एक अच्छी टिप्पणी है, लेकिन ऐसे कई व्यावहारिक मामले प्रतीत होते हैं जहां आप इसे अनदेखा कर सकते हैं। –

0

अजगर 3.6 के साथ शुरू **locals() का असर पहले से ही string#format या बल्कि में शामिल है "स्ट्रिंग शाब्दिक स्वरूपित"।

PEP 498 और Python 3.6 release notes देखें।

संबंधित मुद्दे