“Where is the Duck?”

Open in Colab

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.