Tôi gặp khó khăn trong việc hiểu cách hoạt động của hàm đệ quy được trang trí. Đối với đoạn mã sau:Chức năng đệ quy trang trí trong python
def dec(f):
def wrapper(*argv):
print(argv, 'Decorated!')
return(f(*argv))
return(wrapper)
def f(n):
print(n, 'Original!')
if n == 1: return(1)
else: return(f(n - 1) + n)
print(f(5))
print
dec_f = dec(f)
print(dec_f(5))
print
f = dec(f)
print(f(5))
Đầu ra là:
(5, 'Original!')
(4, 'Original!')
(3, 'Original!')
(2, 'Original!')
(1, 'Original!')
15
((5,), 'Decorated!')
(5, 'Original!')
(4, 'Original!')
(3, 'Original!')
(2, 'Original!')
(1, 'Original!')
15
((5,), 'Decorated!')
(5, 'Original!')
((4,), 'Decorated!')
(4, 'Original!')
((3,), 'Decorated!')
(3, 'Original!')
((2,), 'Decorated!')
(2, 'Original!')
((1,), 'Decorated!')
(1, 'Original!')
15
Đầu tiên một bản in f (n) để tự nhiên nó in mỗi f thời gian 'gốc' (n) được gọi là đệ quy.
Bản thứ hai in def_f (n), vì vậy khi n được chuyển tới trình bao bọc, nó gọi f (n) đệ quy. Nhưng bản thân trình bao bọc không được đệ quy nên chỉ có một 'Trang trí' được in.
Câu hỏi thứ ba giải thích tôi, giống như sử dụng trang trí @dec. Tại sao trang trí f (n) gọi các wrapper năm lần cũng? Dường như với tôi rằng def_f = dec (f) và f = dec (f) chỉ là hai từ khóa liên kết với hai đối tượng hàm giống nhau. Có cái gì khác xảy ra khi chức năng trang trí được đặt cùng tên với cái chưa được trang trí?
Cảm ơn!
tham chiếu với bản gốc 'chức năng f' vẫn còn tồn tại, vì vậy mà một được gọi. Khi bạn thực hiện 'f = dec (f)', bạn sẽ luôn gọi hàm mới. Và hàm mới sẽ gọi ban đầu. – JBernardo
'decorator' có thể không phải là thuật ngữ thích hợp để sử dụng ở đây, vì bạn không bao giờ thực sự áp dụng một trình trang trí cho hàm. Bài kiểm tra cuối cùng của bạn về 'f = dec (f)' gần như (nếu không chính xác) giống như '@dec def f' –