Created
July 7, 2021 19:52
-
-
Save charles-l/c2b113f8fa344ebf57b8facedb184534 to your computer and use it in GitHub Desktop.
Reactive programming in python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from functools import wraps | |
from collections import defaultdict | |
from dataclasses import dataclass, field | |
from typing import Dict, List | |
import ast | |
import inspect | |
class StateFinder(ast.NodeVisitor): | |
def __init__(self, state_name): | |
self.state_name = state_name | |
self.state_attrs = [] | |
def visit_Attribute(self, node): | |
if node.value.id == self.state_name: | |
self.state_attrs.append(node.attr) | |
@dataclass | |
class State: | |
_subscribers: Dict[str, List] = field(default_factory=lambda: defaultdict(list)) | |
x: int = 3 | |
y: int = 1 | |
def __setattr__(self, key, val): | |
super().__setattr__(key, val) | |
for s in self._subscribers[key]: | |
s() | |
def reactive(state_name): | |
def wrapper(f): | |
tree = ast.parse(inspect.getsource(f)) | |
sf = StateFinder(state_name) | |
sf.visit(tree) | |
for attr in sf.state_attrs: | |
state._subscribers[attr].append(f) | |
return f | |
return wrapper | |
## WHOAA REACTIVE PROGRAMMING LETS GOOO | |
state = State() | |
@reactive('state') | |
def doprint(): | |
print(f'{state.x=}, {state.y=}') | |
state.x = 4 | |
state.x = 5 | |
state.y = 2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment