如何捕获特定名称的赋值操作?无需类实现赋值触发方法调用
Nice question! If you want to catch assignments to a specific variable like b without defining custom classes, Python gives you a couple of practical approaches. Let's walk through them:
__setattr__ method Every Python module is an object under the hood, so we can modify its built-in __setattr__ method to intercept module-level variable assignments. This is a lightweight, targeted solution for tracking variables at the script's top level.
import sys def b_is_modified(new_value): print(f"b was updated to: {new_value}") # Add your custom logic here (logging, validation, etc.) # Grab the current module object current_module = sys.modules[__name__] # Save the original __setattr__ to avoid breaking other variable assignments original_setattr = current_module.__setattr__ def custom_setattr(name, value): # Check if we're assigning to 'b' if name == 'b': b_is_modified(value) # Call the original method to actually complete the assignment original_setattr(name, value) # Replace the module's default __setattr__ with our custom version current_module.__setattr__ = custom_setattr # Test it out! b = 10 # Triggers b_is_modified b = "hello world" # Triggers again c = 20 # No trigger (only 'b' is monitored)
This works because when you assign b = something at the module level, Python automatically calls the module's __setattr__ method. We're just inserting our custom check before letting the assignment proceed normally.
sys.settrace() for cross-scope tracking If you need to monitor b assignments across all scopes (module-level, inside functions, etc.), Python's tracing framework with sys.settrace() is the way to go. This lets you hook into every code execution event, including variable assignments.
import sys def b_is_modified(new_value): print(f"b was assigned: {new_value}") # Add your extra logic here def trace_func(frame, event, arg): # Only react to assignment events if event == 'assign': # Check if 'b' is one of the variables being assigned in this frame if 'b' in frame.f_code.co_names: # Fetch the new value (check local scope first, then global) new_value = frame.f_locals.get('b') or frame.f_globals.get('b') b_is_modified(new_value) # Return the trace function to keep monitoring subsequent events return trace_func # Enable tracing sys.settrace(trace_func) # Test assignments in different scopes b = 5 # Triggers b_is_modified def test_function(): b = "local b value" # Also triggers, since we're tracking all scopes test_function()
Notes on this approach:
- It tracks
bassignments everywhere in your script, not just the top level - You may need to adjust value fetching for edge cases (e.g., nested scopes)
- Tracing adds minor performance overhead, so it's ideal for debugging or targeted use cases rather than high-performance production code.
Which option to choose?
- Go with Option 1 if you only care about module-level
bassignments and want a simple, low-overhead solution. - Use Option 2 if you need to monitor
bacross all functions and scopes in your script.
内容的提问来源于stack exchange,提问作者Nae

