Điều bạn đang yêu cầu không thực sự hợp lý.
Biến cục bộ của hàm không có giá trị mọi lúc. Xem xét chức năng này:
def foo(x):
y = x + 27
return y
giá trị của biến cục bộ foo
's y
là gì? Bạn không thể trả lời, câu hỏi thậm chí không có ý nghĩa cho đến khi bạn gọi foo
(và thậm chí sau đó, không cho đến khi dòng y = x + 27
được thực hiện).
Và thậm chí sau đó không chỉ có y
có thể không có giá trị tại thời điểm này, có thể có bất kỳ số nào của các hành vi "đang bay" foo
. Có thể có các chuỗi thực hiện foo
hoặc foo
có thể đệ quy (có thể gián tiếp) để có nhiều cuộc gọi đang diễn ra ngay cả trong một ngăn xếp cuộc gọi. Hoặc foo
có thể là máy phát điện, vì vậy có thể có nhiều chuyến bay thực hiện foo
trên chuyến bay ngay cả khi không có đệ quy (tức làchúng không phải tất cả đều có thể truy cập từ một số phạm vi ngoài cùng của foo
). Vì vậy, mà y
bạn sẽ nhận được giá trị của?
Giá trị y
trong foo
không phải là khái niệm được xác định rõ ràng trừ khi bạn đang nói về trong phạm vi foo
.
Với sự linh hoạt của Python, tôi khá chắc chắn rằng nó có thể làm ngăn xếp khung mẫn và tìm thấy một stack frame cho foo
khi có một hiện đang sống và kéo ra các giá trị của các biến cục bộ của nó lúc bấy giờ. Điều này sẽ là khá khó khăn (nếu không phải là không thể) để làm với một trang trí, bởi vì (trừ khi foo
là một máy phát điện) trang trí chỉ có thể thêm mã wrapper "xung quanh" foo
, có nghĩa là mã điều khiển bởi trang trí chạy trước và sau foo
chạy , vì vậy bạn chỉ có quyền kiểm soát khi khung ngăn xếp của foo
không tồn tại.
Tôi sẽ không cung cấp cho con trỏ cụ thể về chính xác cách thực hiện việc này, bởi vì tôi không biết cách thực hiện. Nghe có vẻ như nó gần như chắc chắn là một ý tưởng tồi mặc dù, trừ khi bạn đang viết một trình gỡ lỗi.
đó làm việc. Tôi đã đồng ý với ý tưởng tồi của nó ngay từ đầu nhưng tôi đã quan tâm để xem liệu nó có khả thi hay không. – Harel
Bí quyết tuyệt vời. Tôi đang thực hiện một trình gỡ rối phải lén lút lấy nội bộ từ một chức năng được trang trí và cho rằng nó hữu ích một cách hợp pháp. Một điều cần lưu ý là tracer() được gọi không chỉ trên sự trở lại của hàm được trang trí, mà còn trên sự trả về của tất cả các hàm được gọi từ bên trong hàm đó. Kể từ khi chức năng trang trí luôn luôn có sự trở lại cuối cùng, (và do đó đặt _locals cuối cùng) nó không quan trọng trong trường hợp này. – Peter