“Where is the Duck?”¶
This notebook illustrates how context-aware components can be developed in PyGlove.
In this example, Duck
is a symbolic class which subscribes the _on_parent_change
and _on_path_change
events. Therefore, when the containing context of a Duck
object is changed, it can respond to such changes.
!pip install pyglove
import pyglove as pg
@pg.members([
('occupied_by', pg.typing.Any())
])
class Venue(pg.Object):
pass
@pg.members([
('size', pg.typing.Enum('small', ['small', 'large'])),
('color', pg.typing.Enum('green', ['green', 'blue', 'black']))
], init_arg_list=['occupied_by', 'size', 'color'])
class Pool(Venue):
def __str__(self):
return f'a {self.size} {self.color} pool'
@pg.members([], init_arg_list=['occupied_by'])
class Cage(Venue):
def __str__(self):
return f'a small cold cage'
def free(self):
self.rebind(occupied_by=None)
class Duck(pg.Object):
def _on_parent_change(self, old_parent, new_parent):
super()._on_parent_change(old_parent, new_parent)
def venue(parent):
if isinstance(parent, Venue):
return str(parent)
return 'nowhere'
print(f'I am moving from {venue(old_parent)} '
f'to {venue(new_parent)}')
def _on_path_change(self, old_path, new_path):
super()._on_path_change(old_path, new_path)
print(f'I am now identified by path "{new_path}"')
def who_am_i(self):
if isinstance(self.sym_parent, Pool):
message = f'I am a happy duck swimming in {str(self.sym_parent)}.'
elif isinstance(self.sym_parent, Cage):
message = f'I am a sad duck wandering in {str(self.sym_parent)}.'
else:
message = f'I am just a duck.'
print(message)
duck = Duck()
duck.who_am_i()
I am just a duck.
cage = Cage(duck)
duck.who_am_i()
I am now identified by path "occupied_by"
I am moving from nowhere to a small cold cage
I am a sad duck wandering in a small cold cage.
cage.free()
I am moving from a small cold cage to nowhere
I am now identified by path ""
pool = Pool(duck)
duck.who_am_i()
I am now identified by path "occupied_by"
I am moving from nowhere to a small green pool
I am a happy duck swimming in a small green pool.