2013-01-21 35 views
8

tôi muốn làm một cái gì đó như thế này:Bí danh cho các hoạt động từ điển trong Python

f[frozenset((1,3,4))] = 5 
f[frozenset((1,))] = 3 

nhưng nó chỉ là đau đớn để gõ những tất cả các thời gian, là có anyway để có bí danh cho điều này? Tôi biết trong C++ có thể có một hàm trợ giúp trả về tham chiếu để bạn có thể chỉ cần nhập:

F(1,3,4) = 5 
F(1) = 3 

với F làm hàm trợ giúp. Cảm ơn rất nhiều!

Trả lời

13

Tôi nghĩ rằng điều này thực sự chỉ có thể đạt được thông qua một lớp con:

class FrozenSetDict(dict): 
    def __setitem__(self,idx,value): 
     try: 
      dict.__setitem__(self,frozenset(idx),value) 
     except TypeError: 
      dict.__setitem__(self,frozenset((idx,)),value) 

d = FrozenSetDict() 
d[1,2,3] = 4 
d[1] = 5 
print d 

sản lượng:

{frozenset([1, 2, 3]): 4, frozenset([1]): 5} 

này giới thiệu một sự bất đối xứng giữa __getitem____setitem__ mà có thể dễ dàng được cố định bằng cách tái định nghĩa __getitem__ theo cách tương tự.

Điều này có vẻ hơi lộn xộn - Thật vậy. Tại sao yêu cầu một phân lớp? Điều đó chỉ gây khó khăn hơn khi đặt các đối tượng không phải là frozenset vào từ điển của bạn làm khóa. Bạn có thể dễ dàng sử dụng công thức này mặc dù để tạo ra một đối tượng proxy mà sẽ làm điều này với dict của bạn:

#I don't like the name of this class -- I'm open to suggestions :) 
class FrozenSetProxy(object): 
    def __init__(self,obj): 
     self.obj = obj 

    def __setitem__(self,idx,value): 
     try: 
      self.obj[frozenset(idx)] = value 
     except TypeError: 
      self.obj[frozenset((idx,))] = value 

    def __getitem__(self,idx): 
     try: 
      return self.obj[frozenset(idx)] 
     except TypeError: 
      return self.obj[frozenset((idx,))] 

d = dict() 
F = FrozenSetProxy(d) 
F[1,2,3] = 4 
F[1] = 5 
print d 
print F[1] 
+0

Đây là một quá mức cần thiết phải không? – delnan

+0

@mgilson: Tuyệt vời, mặc dù nó sẽ là tốt để hiển thị một ví dụ về cách sử dụng của nó. –

+0

@delnan - Sắp xếp. Tôi không thấy bất kỳ cách nào khác để có được cú pháp mà OP đang yêu cầu mặc dù. – mgilson

4

Chẳng gì bằng một C++ tài liệu tham khảo bằng Python là, và cú pháp bạn sử dụng là bất hợp pháp để khởi động (theo lời của trình phân tích cú pháp: can't assign to function call). Bạn có thể mô phỏng nó với một đối tượng hoặc một lớp con dict để tùy chỉnh __getitem__ của nó. Nhưng có một cách đơn giản và ít xâm nhập: Vượt qua giá trị cho các helper quá, và để cho nó xử lý các công việc:

def blah(f): 
    def F(*args, value): 
     f[frozenset(args)] = value 
    F(1, 3, 4, value=5) 
    F(1, value=3) 

Lưu ý rằng đây sử dụng một tính năng 3 Python, từ khóa chỉ tham số. Nếu bạn cần nó để làm việc với Python 2, bạn có thể mô phỏng cú pháp cuộc gọi bằng cách chấp nhận **kwdargs:

def F(*args, **kwds): 
    # optional: check that no other keyword arguments were passed 
    f[frozenset(args)] = kwds['value'] 
Các vấn đề liên quan