In Python you can achieve the functionality of executing a callback when a variable changes using various techniques. One common method is to use properties or setter methods along with the observer pattern. Below, I'll provide five examples demonstrating different ways to implement this functionality, along with explanations and sample outputs.
Example 1: Using a Property
class VariableWatcher:
def __init__(self):
self._value = None
@property
def value(self):
return self._value
@value.setter
def value(self, new_value):
self._value = new_value
self.on_change(new_value)
def on_change(self, new_value):
print(f"Variable value changed to: {new_value}")
# Example usage
watcher = VariableWatcher()
watcher.value = 10
watcher.value = 20
Explanation:
- We define a class
VariableWatcherwith a private attribute_valueto store the variable value. - We define a
valueproperty with a setter method. When thevalueproperty is set, it triggers the setter method, which updates the_valueattribute and calls theon_changemethod. - The
on_changemethod is where you would put your callback logic. In this example, it simply prints the new value. - When you run this code, you'll see that the
on_changemethod gets called each time thevalueproperty is set.
Output:
Variable value changed to: 10
Variable value changed to: 20
Example 2: Using a custom setter method
class VariableWatcher:
def __init__(self):
self._value = None
def set_value(self, new_value):
self._value = new_value
self.on_change(new_value)
def on_change(self, new_value):
print(f"Variable value changed to: {new_value}")
# Example usage
watcher = VariableWatcher()
watcher.set_value(10)
watcher.set_value(20)
Explanation:
- This example is similar to the first one, but instead of using a property, we have a custom setter method
set_value. - Whenever
set_valueis called, it updates the_valueattribute and calls theon_changemethod. - The
on_changemethod remains the same as in the previous example.
Output: (Same as Example 1)
Example 3: Using custom observer pattern
class VariableWatcher:
def __init__(self):
self._value = None
self.observers = []
def set_value(self, new_value):
self._value = new_value
self.notify(new_value)
def add_observer(self, observer):
self.observers.append(observer)
def notify(self, new_value):
for observer in self.observers:
observer(new_value)
# Example usage
def callback(new_value):
print(f"Variable value changed to: {new_value}")
watcher = VariableWatcher()
watcher.add_observer(callback)
watcher.set_value(10)
watcher.set_value(20)
Explanation:
- This example implements a simple observer pattern.
- The
VariableWatcherclass maintains a list of observers (callbacks). - The
add_observermethod allows adding new observers to the list. - When the
set_valuemethod is called, it updates the_valueattribute and notifies all observers by calling them with the new value. - In this example, we define a callback function
callbackand add it as an observer.
Output: (Same as Example 1)
Example 4: Using property decorator with a function
class VariableWatcher:
def __init__(self):
self._value = None
@property
def value(self):
return self._value
@value.setter
def value(self, new_value):
self._value = new_value
self.on_change(new_value)
def on_change(self, new_value):
print(f"Variable value changed to: {new_value}")
# Example usage
watcher = VariableWatcher()
def callback(new_value):
print(f"Callback: Variable value changed to: {new_value}")
watcher.value = 10
watcher.on_change = callback # Replace the callback
watcher.value = 20
Explanation:
- This example is similar to Example 1, but we're demonstrating that you can change the
on_changebehavior dynamically. - After creating an instance of
VariableWatcher, we define acallbackfunction. - We then replace the
on_changemethod with this callback function dynamically by assigning it to theon_changeattribute of the instance. - When
valueis updated, it triggers theon_changemethod, which now calls our callback function instead.
Output:
Variable value changed to: 10
Callback: Variable value changed to: 20
Example 5: Using a library (watchdog)
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class MyHandler(FileSystemEventHandler):
def on_modified(self, event):
if event.src_path == "./myfile.txt":
print("File modified! Callback triggered.")
# Example usage
observer = Observer()
observer.schedule(MyHandler(), path='.')
observer.start()
# Simulate file modification
with open("myfile.txt", "w") as f:
f.write("Hello, world!")
observer.stop()
observer.join()
Explanation:
- In this example, we use the
watchdoglibrary to monitor file system events. - We define a custom event handler
MyHandlerwhich inherits fromFileSystemEventHandler. - We override the
on_modifiedmethod to specify what should happen when a file is modified. In this case, it prints a message. - We create an
Observerinstance, attach our event handler to it, and start observing the current directory. - Then, we simulate a file modification by creating a file
"myfile.txt"and writing some content to it. - Finally, we stop the observer and join it.
Output:
File modified! Callback triggered.
These examples showcase different ways to implement callbacks when a variable changes in Python, ranging from basic property setters to more advanced techniques using libraries like watchdog.
Top comments (0)