Skip to content

Instantly share code, notes, and snippets.

@perryism
Last active December 8, 2025 18:47
Show Gist options
  • Select an option

  • Save perryism/359ec23274946823464bd28662b47603 to your computer and use it in GitHub Desktop.

Select an option

Save perryism/359ec23274946823464bd28662b47603 to your computer and use it in GitHub Desktop.
A delegator
from typing import Any
import unittest
class Delegator:
def __init__(self, instance, method_name):
self.instance = instance
self.method_name = method_name
def __getattr__(self, name):
if name == self.method_name:
return getattr(self.instance, name)
raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'")
def __call__(self, *args: Any, **kwds: Any) -> Any:
return getattr(self.instance, self.method_name)(*args, **kwds)
def __get__(self, instance, owner):
if instance is None:
return self
return getattr(self.instance, self.method_name)
class Bar:
buzz = "buzz"
def hello(self):
return "Hello from Bar"
class Foo:
bar = Bar()
hello = Delegator(bar, 'hello')
buzz = Delegator(bar, 'buzz')
class TestMe(unittest.TestCase):
def test_delegator(self):
foo = Foo()
self.assertEqual(foo.bar.hello(), foo.hello())
self.assertEqual(foo.bar.buzz, foo.buzz)
class Delegator:
def __getattr__(self, name):
if hasattr(self, 'delegate'):
target_attr, methods = self.delegate
if name in methods:
target = getattr(self, target_attr)
return getattr(target, name)
raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'")
class Buzz(Delegator):
delegate = ['model', ['hello', 'bye']]
def __init__(self):
self.model = Bar()
b = Buzz()
print(b.hello())
print(b.bye("Joe"))
b.not_implemented()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment