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
VariableWatcher
with a private attribute_value
to store the variable value. - We define a
value
property with a setter method. When thevalue
property is set, it triggers the setter method, which updates the_value
attribute and calls theon_change
method. - The
on_change
method 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_change
method gets called each time thevalue
property 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_value
is called, it updates the_value
attribute and calls theon_change
method. - The
on_change
method 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
VariableWatcher
class maintains a list of observers (callbacks). - The
add_observer
method allows adding new observers to the list. - When the
set_value
method is called, it updates the_value
attribute and notifies all observers by calling them with the new value. - In this example, we define a callback function
callback
and 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_change
behavior dynamically. - After creating an instance of
VariableWatcher
, we define acallback
function. - We then replace the
on_change
method with this callback function dynamically by assigning it to theon_change
attribute of the instance. - When
value
is updated, it triggers theon_change
method, 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
watchdog
library to monitor file system events. - We define a custom event handler
MyHandler
which inherits fromFileSystemEventHandler
. - We override the
on_modified
method to specify what should happen when a file is modified. In this case, it prints a message. - We create an
Observer
instance, 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)