2011-08-19 51 views
5

Gần đây tôi đã làm rất nhiều chương trình âm nhạc có trụ sở, và như vậy thấy mình làm loại điều rất nhiều để đối phó với thiếu siêu dữ liệu trong một số bài hát:Chuỗi định dạng trong python

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

Có một cách sạch hơn để làm điều này? Tôi đã cố gắng ghi đè __missing__ như vậy nhưng các phím bị thiếu vẫn ném một KeyError:

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

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

Chỉnh sửa: Xin lỗi tôi phải rõ ràng hơn, về cơ bản những điều sau đây phải hoạt động.

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

Một vài người đã chỉ ra rằng ** s không cần thiết.

Chỉnh sửa 2: Tôi đã "giải quyết" sự cố của mình, ít nhất là sự hài lòng của tôi. Nó có thể gây tranh cãi cho dù điều này là sạch hơn, nhưng nó có hiệu quả đối với tôi.

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) 

Vì vậy, sau đây sẽ trở về 'notAKey Unknown'

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

Chỉ một đề xuất nhỏ: Có vẻ như bạn đang làm đơn xin sử dụng hàng ngày và có thể phân phối nó. Nếu bạn muốn, sau đó bạn nên bắt đầu sử dụng [gettext] (http://docs.python.org/library/gettext.html) - bạn sẽ tự cứu mình khỏi rất nhiều rắc rối sau này. – nagisa

Trả lời

-1

Tôi thích phiên bản Jared nhưng nếu bạn thực sự muốn thực hiện điều đó cho mình, đây là một cách:

>>> 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 để hiển thị cách tự mình triển khai, nếu bạn cần tùy chỉnh thêm. –

+0

'khóa trong self.keys()' chuyển hoạt động O (1) thành O (n). Ngoài ra, dòng mới là miễn phí. – habnabit

+0

Điều này ** không hoạt động ** bởi vì '** foo' chuyển đổi thứ được truyền thành dict thông thường. Bạn đã thử nghiệm nó trên trường hợp thực tế đưa ra? –

3

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

Bạn đã thử nhập defaultdict từ collections?

from collections import defaultdict 

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

Dưới đây là một câu hỏi tương tự: How to make a python dictionary that returns key for keys missing from the dictionary instead of raising KeyError?:

+0

Điều này ** không hoạt động ** vì cùng một lý do đoạn mã thứ hai của OP không hoạt động. Tôi không biết tại sao bạn tin rằng nó sẽ hoạt động. Bạn đã thử nghiệm nó trong khi đi qua '** your_instance' chưa? –

-1

Vâng, một lựa chọn tôi có thể nghĩ đến là sử dụng một phương pháp mà vốn đã có thể cung cấp cho bạn với các giá trị mặc định, cụ thể là getattr. Nếu bạn muốn chuyển đổi dict của bạn thành một đối tượng chuyển phím vào các thuộc tính, bạn có thể sử dụng an toàn getattr để truy xuất giá trị:

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

Bây giờ bạn chỉ có thể sử dụng:

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

Tóm tắt: đóng gói bài hát trong một lớp học.

Nghe có vẻ như tôi là một bài hát là một kiểu dữ liệu chính trong mã của bạn và xứng đáng có một lớp chuyên dụng để đại diện cho nó. Bởi tất cả các phương tiện sử dụng một dict bên trong lớp để lưu trữ dữ liệu nhưng cố gắng và di chuyển đến một mức độ trừu tượng cao hơn một dict.

Bạn nên nhắm đến lớp học này để cung cấp tất cả các dịch vụ cần thiết để hỗ trợ các hoạt động bạn thực hiện trên các bài hát. Nhà tất cả các mã định dạng trong lớp để nó không nằm rải rác về mã của bạn sử dụng các mục bài hát. Thật vậy, bạn sẽ tìm thấy tất cả các loại hoạt động mà muốn trở thành phương pháp của lớp này.

Đối với việc triển khai định dạng, nó không quan trọng nếu nó hơi dài vì bạn chỉ viết ở một nơi.

1

Thật không may, khi bạn gọi một phương thức với cú pháp **foo, nó đang chuyển đổi foo chỉ thành một lệnh chính quy.Giải pháp sạch nhất có lẽ là giải pháp bạn đã đăng trong đoạn trích đầu tiên của mình.

+0

Điểm tốt. Tôi thích lớp học hơn. – leoluk

Các vấn đề liên quan