2011-08-19 17 views
5

हाल ही में मैं संगीत आधारित प्रोग्रामिंग का एक बहुत कुछ कर दिया गया है, और इस तरह के रूप में अपने आप को बात इस तरह का एक बहुत कुछ कर कुछ गाने में मेटाडाटा लापता से निपटने के लिए लगता है:स्ट्रिंग अजगर में स्वरूपण

default = {'title': 'Unknown title', 'artist': 'unknown Artist'} 
default.update(song) 
print '{title} - {artist}'.format(**default) 

है वहाँ ऐसा करने के लिए एक क्लीनर तरीका? मैं इतना लेकिन लापता कुंजी अभी भी एक KeyError फेंक की तरह __missing__ अधिभावी की कोशिश की:

class Song(dict): 
    # dictionary with some nice stuff to make it nicer 

    def __missing__(self, key): 
     return 'Unknown {key}'.format(key = key) 

संपादित करें: माफ करना, मैं स्पष्ट किया जाना चाहिए था, मूल रूप से निम्नलिखित काम करना चाहिए।

s = Song() 
print '{notAKey}'.format(s) 

कुछ लोगों ने इंगित किया है कि ** आवश्यक नहीं हैं।

संपादित करें 2: कम से कम मेरी संतुष्टि के लिए मैंने अपनी समस्या हल कर ली है। यह बहस योग्य है कि यह क्लीनर है या नहीं, लेकिन यह मेरे लिए काम करता है।

from string import Formatter 

class DefaultFormatter(Formatter): 

    def get_value(self, key, args, kwargs): 
     # Try standard formatting, then return 'unknown key' 

     try: 
      return Formatter.get_value(self, key, args, kwargs) 
     except KeyError: 
      return kwargs.get(key, 'Unknown {0}'.format(key)) 

class Song(dict): 

    def format(self, formatString): 
     # Convenience method, create a DefaultFormatter and use it 

     f = DefaultFormatter() 
     return f.format(formatString, **self) 

तो निम्नलिखित 'अज्ञात notAKey'

k = Song() 
print k.format('{notAKey}') 
+0

बस एक छोटी सी सिफारिश: ऐसा लगता है कि आप दैनिक उपयोग के लिए आवेदन कर रहे हैं, और शायद इसे वितरित कर सकते हैं। यदि आप करेंगे, तो आपको [gettext] (http://docs.python.org/library/gettext.html) का उपयोग शुरू करना चाहिए - आप बाद में बहुत परेशानी से खुद को बचाएंगे। – nagisa

उत्तर

-1

मैं जारेड के संस्करण पसंद करते हैं वापस आ जाएगी, लेकिन अगर आप वास्तव में यह अपने आप को लागू करना चाहते हैं, यहाँ एक तरीका है:

>>> class Song(dict): 
...  def __getitem__(self, key): 
...    if key in self.keys(): return super(Song, self).__getitem__(key) 
...    return 'Unknown {key}'.format(key=key) 
... 
>>> s = Song() 
>>> s['foo'] 
'Unknown foo' 
>>> s['foo'] = 1 
>>> s['foo'] 
1 
+0

+1 यह दिखाने के लिए कि आपको इसे कैसे कार्यान्वित किया जाए, यदि आपको और अनुकूलन की आवश्यकता है। –

+0

'self.keys() में कुंजी' ओ (1) ऑपरेशन ओ (एन) में बदल जाती है। इसके अलावा, न्यूलाइन मुक्त हैं। – habnabit

+0

यह ** काम नहीं करता ** क्योंकि '** foo' पास की चीज़ को सामान्य नियम में परिवर्तित करता है। क्या आपने इसे वास्तविक मामले पर परीक्षण किया था? –

3

Warning: This solution does not actually work to solve the original question regarding '{title} - {artist}'.format(**default)

क्या आपने collections से defaultdict आयात करने का प्रयास किया है?

from collections import defaultdict 

class Song(defaultdict): 
    def __missing__(self, key): 
     return 'Unknown {key}'.format(key = key) 

यहाँ एक समान सवाल है: How to make a python dictionary that returns key for keys missing from the dictionary instead of raising KeyError?:

+0

यह ** काम नहीं करता ** इसी कारण से ओपी का दूसरा स्निपेट काम नहीं करता है। मुझे नहीं पता कि आप क्यों मानते हैं कि यह काम करेगा। क्या आपने अभी तक '** your_instance' पास करते समय इसका परीक्षण किया है? –

-1

ठीक है, एक ही विकल्प मैं के बारे में सोच सकते हैं एक तरीका है कि स्वाभाविक मूलभूत मूल्यों, अर्थात् getattr प्रदान कर सकते हैं का उपयोग कर रहा है। आप किसी ऑब्जेक्ट विशेषताओं में कुंजी मोड़ में अपने dict बदलना चाहते हैं तो आप सुरक्षित getattr इस्तेमाल कर सकते हैं मूल्यों को नहीं निकाला जा:

class AttributeDict(): 
    def __init__(self, source_dict): 
     self._ATTRIBUTE_DICT_source_dict = source_dict 
     for key in source_dict.keys(): 
      setattr(self, str(key), source_dict[key]) 

अब आप बस का उपयोग कर सकते हैं:

song = AttributeDict(song) 
artist = getattr(song, 'artist', 'Unknown Artist') 
6

कार्यकारी सारांश: एक वर्ग में गीत encapsulate।

ऐसा लगता है कि एक गीत की तरह यह आपके कोड में एक प्राथमिक डेटा प्रकार है और इसे प्रस्तुत करने के लिए एक समर्पित वर्ग होने के योग्य है। हर तरह से डेटा को स्टोर करने के लिए कक्षा में आंतरिक एक निर्देश का उपयोग करें, लेकिन एक नियम की तुलना में उच्च स्तर के अमूर्तता की कोशिश करें और आगे बढ़ें।

आपको इस कक्षा के लिए गानों पर किए गए संचालनों का समर्थन करने के लिए आवश्यक सभी सेवाएं प्रदान करने का लक्ष्य रखना चाहिए। कक्षा में सभी स्वरूपण कोड हाउस करें ताकि यह आपके कोड के बारे में बिखरा हुआ न हो जो गीत आइटम का उपयोग करता हो। दरअसल आपको ऐसे सभी प्रकार के ऑपरेशन मिलेंगे जो इस वर्ग के तरीके बनना चाहते हैं।

प्रारूपण के कार्यान्वयन के लिए, इससे कोई फर्क नहीं पड़ता कि यह थोड़ी देर तक हवादार है क्योंकि आप इसे केवल एक ही स्थान पर लिखते हैं।

1

दुर्भाग्य से, जब आप **foo सिंटैक्स के साथ कोई विधि कॉल करते हैं, तो यह केवल नियमित नियम के लिए foo परिवर्तित कर रहा है।सबसे साफ समाधान शायद वह है जिसे आपने अपने पहले स्निपेट में पोस्ट किया था।

+0

अच्छा बिंदु। मैं कक्षा एक पसंद करता हूँ। – leoluk