Skip to content

Instantly share code, notes, and snippets.

@XoseLluis
Created July 6, 2022 15:46
Show Gist options
  • Save XoseLluis/5ab3aee5be1da758c693f3805ca1ddac to your computer and use it in GitHub Desktop.
Save XoseLluis/5ab3aee5be1da758c693f3805ca1ddac to your computer and use it in GitHub Desktop.

Revisions

  1. XoseLluis created this gist Jul 6, 2022.
    40 changes: 40 additions & 0 deletions intercept_instance.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,40 @@
    # In Groovy we can add interception to an instance (not to a whole class) by means of adding it to the instance metaclass
    # we can do something like that in Python by creating a new class that inherits the original class of the instance, and changing the class of the instance
    # in that new class we implement __getattribute__

    class Person:
    def __init__(self, name):
    self.name = name

    def say_hi(self, person):
    #print("inside say_hi")
    return f"Hi person, I'm {self.name}"


    def add_interception_to_instance(obj, interceptor_fn):
    class Interceptor_class(obj.__class__):
    def __getattribute__(self, name):
    interceptor_fn(self, name)
    return object.__getattribute__(self, name)
    obj.__class__ = Interceptor_class

    p1 = Person("Xuan")
    print(p1.say_hi("Francois"))
    # Hi person, I'm Xuan

    def logger_interceptor_fn(obj, attr):
    print(f"intercepting access to {attr}")

    add_interception_to_instance(p1, logger_interceptor_fn)
    print(p1.say_hi("Francois"))
    #interception happens:
    # intercepting access to say_hi
    # intercepting access to name
    # Hi person, I'm Xuan
    print(isinstance(p1, Person))
    # True

    # other instances of Person are not intercepted
    p2 = Person("Iyan")
    print(p2.say_hi("Francois"))
    # Hi person, I'm Iyan