Bạn có một vài tùy chọn. Đầu tiên, lưu ý rằng g trong ví dụ của bạn không thực sự là một hàm cục bộ (ví dụ, không được gán bên trong nó), nó là một global (nghĩa là chưa được gán cho một biến cục bộ). Điều này có nghĩa là nó sẽ được tra cứu trong module mà hàm được định nghĩa. Điều này thật may mắn vì không có cách nào thay đổi người dân bên ngoài (thiếu vá mã byte), khi chúng được gán khi hàm chạy, không phải trước đó.
Một tùy chọn đơn giản là đưa hàm của bạn vào không gian tên của mô-đun. Điều này sẽ làm việc, nhưng sẽ ảnh hưởng đến mọi chức năng trong mô-đun đó truy cập biến, thay vì chỉ là một hàm.
Để chỉ ảnh hưởng đến một chức năng, bạn cần thay vào đó chỉ ra rằng func_globals ở một nơi khác. Thật không may, đây là một thuộc tính chỉ đọc, nhưng bạn có thể làm những gì bạn muốn bằng cách tái tạo lại chức năng với cơ thể giống nhau, nhưng một namespace toàn cục khác nhau:
import new
f = new.function(f.func_code, {'g': my_g_function}, f.func_name, f.func_defaults, f.func_closure)
f bây giờ sẽ có indentical, ngoại trừ việc nó sẽ xem xét cho globals trong dict được cung cấp. Lưu ý rằng điều này sẽ khôi phục toàn bộ không gian tên chung - nếu có các biến có f thì tra cứu, hãy đảm bảo bạn cũng cung cấp các biến đó. Điều này cũng khá khó khăn mặc dù, và có thể không hoạt động trên các phiên bản của python khác với cpython.
mục tiêu cuối cùng của bạn sử dụng kỹ thuật kỳ lạ này là gì? Tại sao bạn không thể xác định g() trước f()? –
Tôi đã cố gắng để gây rối với không gian tên của một chức năng ở thời gian chạy trước đó (để thử nghiệm/mocking) và thất bại ... chỉ FYI. –
heck là 'add_to_locals' là gì? Nó dường như không tồn tại đối với tôi. Đối tượng 'AttributeError: 'function' không có thuộc tính 'add_to_locals'' –