Tôi có thể xác định một chức năng, khi được gọi, chèn người dân địa phương mới vào phạm vi của người gọi không? Tôi có cảm giác rằng việc chuyển số người địa phương của người gọi() vào chức năng có thể hoạt động, nhưng có cách nào để làm những gì tôi muốn mà không cần phải thực hiện việc này không?Tiêm các biến vào phạm vi của người gọi?
Trả lời
Theo quy tắc của Python, bạn không thể thay đổi người gọi locals
; trong các triển khai hiện tại, nếu bạn thử (ví dụ như với ma thuật đen Anurag gợi ý), bạn sẽ không nhận được ngoại lệ (mặc dù tôi muốn thêm kiểm tra lỗi đó vào một số phiên bản tương lai), nhưng về cơ bản sẽ không hoạt động nếu người gọi của bạn một hàm (không phải nếu người gọi của bạn là mã cấp cao nhất của mô-đun) - các biến cục bộ thực tế của người gọi sẽ không bị ảnh hưởng. Điều này giữ cho dù người gọi locals
của bạn được chuyển vào một cách rõ ràng hoặc được tìm nạp thông qua ma thuật đen: họ vẫn cần được coi là một dict chỉ đọc nếu mã của bạn có bất kỳ sự tỉnh táo nào. Thay vào đó, bạn có thể có thẻ người gọi trong một dict rõ ràng, thực, bình thường (có thể được khởi tạo từ locals()
nếu bạn muốn), và tất cả các thay đổi mã của bạn thực hiện trong dict đó vẫn sẽ ở đó để sử dụng của người gọi - - không phải là "tên gọi mới" trong phạm vi địa phương của người gọi, nhưng chức năng cũng giống nhau nếu người gọi cần sử dụng x['foo']
hoặc x.foo
hoặc (như bạn muốn) chỉ tên thanh là foo
.
BTW, sử dụng cú pháp thuộc tính truy cập chứ không phải là cú pháp lập chỉ mục dict, bạn có thể làm:
class Bunch(object): pass
...
# caller code
b = Bunch()
thefun(b)
print b.foo
...
# called function
def thefun(b):
b.foo = 23
này cũng bao gồm, với một biến thể nhỏ bé, trường hợp trong đó thefun
muốn làm việc với cú pháp lập chỉ mục dict (nói rằng nội dung của nó là b['foo'] = 23
thay vì b.foo = 23
): trong trường hợp đó, người gọi chỉ cần sử dụng thefun(vars(b))
thay vì đồng bằng thefun(b)
, nhưng nó có thể tiếp tục làm việc với cú pháp truy cập b.foo
sau đó.
Được rồi, có vẻ như không thực sự có thể làm những gì tôi muốn. Cảm ơn ý tưởng truy cập thuộc tính; nếu tôi không thể có barenames (x), điều đẹp nhất tiếp theo có lẽ là thuộc tính access (context.x). – jogloran
Điều này là không đúng, xem câu trả lời dưới đây bằng cách sử dụng mô-đun kiểm tra của python xây dựng để xem cách thực hiện của nó. Python là một ngôn ngữ động hoàn chỉnh, bạn có thể ghi đè lên trình thông dịch riêng của nó nếu bạn muốn. Tôi chỉ trích dẫn http://xkcd.com/353/ – Pykler
Alex là chính xác. Câu trả lời của @ Pykler chỉ hoạt động trong một trường hợp cụ thể và không nói chung. – ferrouswheel
Kiểm tra inspect module, được sử dụng bởi minimock để giả lập phạm vi của người gọi.
Mã này phải làm những gì bạn muốn chính xác:
import inspect
def mess_with_caller():
stack = inspect.stack()
try:
locals_ = stack[1][0].f_locals
finally:
del stack
locals_['my_new_function'] = lambda : 'yaaaaaay'
mess_with_caller()
print my_new_function()
>>> Output: 'yaaaaaay'
Đây không phải là có thể mà không thay đổi API, như CPython giữ một tham chiếu đến các danh sách đối số trong suốt thời gian của cuộc gọi chức năng.
Một cách để thực hiện điều này là chuyển một đối tượng và xóa trạng thái bên trong của đối tượng khi sử dụng nó.
class Obj(object):
def __init__(self, state):
self.state = state
def f(o):
# Do stuff with o.state
del o.state
- 1. Angularjs: Tiêm gạch dưới vào phạm vi $
- 2. Phạm vi của các biến trong KSH
- 3. python biến phạm vi
- 4. PHP đóng cửa Phạm vi của các biến
- 5. Phạm vi biến trong các hàm VBScript
- 6. Phạm vi của các biến trong câu lệnh
- 7. coldfusion CFM Biến phạm vi
- 8. Lambda biến phạm vi
- 9. phạm vi biến cmake, add_subdirectory
- 10. Lưu phạm vi để biến
- 11. Coffeescript/Javascript biến phạm vi
- 12. JSF phạm vi ứng dụng instantiation và tiêm
- 13. Phạm vi biến trong C++
- 14. Giới hạn phạm vi biến
- 15. Phạm vi gọi lại JavaScript
- 16. Phạm vi của typedefs
- 17. Biến phạm vi vấn đề
- 18. Junit kiểm tra phạm vi biến lớp
- 19. Làm cách nào để đưa biến vào phạm vi của chỉ thị?
- 20. Phân tích phạm vi ngày thông minh của đầu vào của con người?
- 21. jquery sự kiện ủy nhiệm biến phạm vi với các cuộc gọi liên tiếp
- 22. Angularjs: gọi phạm vi khác trong iframe
- 23. Lấy Phạm vi đã Chọn của Người dùng
- 24. Làm cách nào để ném ngoại lệ từ phạm vi của người gọi?
- 25. Phạm vi Javascript trong chức năng được tiêm
- 26. Câu hỏi phạm vi biến cục bộ
- 27. C++ Phạm vi biến thành viên tĩnh
- 28. Phạm vi của các lớp lồng nhau?
- 29. Hamlet tự động truy cập vào các biến trong phạm vi
- 30. Phạm vi biến đổi trong dưa chuột
Giả sử người gọi được mong đợi hiểu được rủi ro của callee khi đi đến thị trấn với người dân địa phương. – jogloran
Âm thanh như một công thức cho mì spaghetti –
Nó được gọi là "trả lại". –