2011-12-17 18 views
12

Tôi nhận đoạn mã sau đây từ trang web của Peter Norvig; đó là một trang trí để cho phép ghi nhớ trên các cuộc gọi hàm (caching các cuộc gọi trước đến hàm để thay đổi đệ quy theo hàm mũ thành một chương trình động đơn giản).Tại sao một dòng trong hàm python này cần thiết? (recoion memoized)

def memo(f): 
    table = {} 
    def fmemo(*args): 
     if args not in table: 
      table[args] = f(*args) 
     return table[args] 
    fmemo.memo = table 
    return fmemo 

Mã hoạt động tốt, nhưng tôi tự hỏi tại sao dòng thứ hai thành dòng cuối cùng là cần thiết. Điều này rõ ràng là một khoảng trống trong kiến ​​thức của tôi về Python, nhưng loại bỏ các dòng và chạy một hàm fibonacci đơn giản, nó vẫn có vẻ làm việc. Điều này có liên quan đến việc ghi nhớ nhiều chức năng cùng lúc không? Tại sao biến thành viên của fmemo được gọi là memo (giả sử nó không phải là một trùng hợp ngẫu nhiên)?

Cảm ơn!

+0

lõm mã của bạn trông không đúng. Đó có phải là hàm lồng nhau không? – MAK

+0

FTFY ........... – katrielalex

+1

BTW này đã được triển khai trong Python 3.2 dưới dạng ['functools.lru_cache'] (http://docs.python.org/dev/library/functools.html#functools .lru_cache). – katrielalex

Trả lời

12

Vì chức năng là đối tượng giống như bất kỳ thứ gì khác, bạn có thể đặt thuộc tính trên chúng. Xem:

>>> def foo(): pass 
>>> foo.x = 1 
>>> foo.x 
1 

Dòng thứ hai-to-bộ bộ nhớ cache nội bộ của các giá trị như một thuộc tính trên đối tượng chức năng, do đó phơi bày nó. Điều này có nghĩa là bạn có thể thực hiện một chức năng ghi nhớ và ghi nhớ với bộ nhớ cache như bạn sẽ làm, mà không cần phải gọi nó. Điều này có thể thuận tiện.


Ví dụ:

>>> @memo 
... def id(x): return x 
>>> id(1) 
1 
>>> id(2) 
2 
>>> id.memo 
{(2,): 2, (1,): 1} 
+3

Tôi muốn thêm vào điều này rằng nó không * cần thiết *, do đóng cửa. Như bạn nói, khả năng can thiệp vào nó hoặc truy cập các giá trị mà không cần gọi nó là điều quan trọng. –

+0

Thật vậy, biến 'table' đã đóng cũng đặt tên cho bộ đệm (thực ra là có vấn đề nếu' memo' được gán lại bên ngoài) ... nhưng +1. –

+0

Thật vậy, việc gán lại 'memo' sẽ là xấu. – katrielalex

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