Skip to main content

Build Status

Delegate methods made easy

This tiny library implements two simple ways of method or property delegators, by descriptors and by class decorators.

From wikipedia, what is delegation:

In object-oriented programming, delegation refers to evaluating a member (property or method) of one object (the receiver) in the context of another original object (the sender). Delegation can be done explicitly, by passing the sending object to the receiving object, which can be done in any object-oriented language; or implicitly, by the member lookup rules of the language, which requires language support for the feature.

Installation

This is python3 only, but it's very simple library with no dependences, it would not be hard to port it to python2, contributions are welcome!

pip install delegateto

Examples

DelegateTo descriptor let you delegate method or property calls

The argument name is the name of the method or property that you want to delegate, for example.

from delegateto import DelegateTo
class Foo:
    upper = DelegateTo('v')
    __len__ = DelegateTo('l')
    __iter__ = DelegateTo('l')

    def __init__(self, v, l):
        self.v = v
        self.l = l

foo = Foo('hello world', [1, 2, 3])

To call a method just call its delegator

foo.up() # => 'HELLO WORLD'

Magic methods are supported

len(foo) # => 3
[x*2 for x in foo] # => [2, 4, 6]

At class parsing time is not possible for DelegateTo to know to what attribute you're assigning it to. For example foo = DelegateTo('bar') Pay attention that DelegateTo doesn't receive any information about foo attribute, but it will discover this latter. The method name is discovered at the first call. This is done by iterating over all the object's attributes. Once found the method is cached and no search is performed in the subsequent calls.

Still, if you need to avoid this iteration you can initialize the method name with the same name of the attribute name.

For example

class Foo:
    upper = DelegateTo('v', 'upper')
    def __init__(self, v):
        self.v = v

This make possible the creation of aliases

class Foo:
    up = DelegateTo('v', 'upper')
    def __init__(self, v):
        self.v = v

Foo('hello').up() # => 'HELLO'

In this context 'self' has a special meaning of delegating a method to another method in the same object. For example

class Foo:
    foo = DelegateTo('self', 'bar')
    def bar(self):
        return 'bar'

Foo().foo() # => 'bar'

There is another way of creating delegators with class decorators, here is how

from delegateto import delegate
@delegate('v', 'upper')
@delegate('v', 'lower')
@delegate('v', 'wrong_method')
@delegate('not_an_attribute', 'wrong_attribute')
class Foo:
    def __init__(self, v):
        self.v = v

Foo('foo').upper() # => 'FOO'
Foo('FOO').lower() # => 'foo'

Foo('foo').wrong_method() # => raises AttributeError: 'str' object has no attribute 'wrong_method'

Foo('foo').wrong_attribute() # => raises AttributeError: 'Foo' object has no attribute 'not_an_attribute'

As a shortcut you can use pass any number of methods or properties to delegate

@delegate('v', 'upper', 'lower')
class Foo:
    def __init__(self, v):
        self.v = v

Example using properties instead of methods

class Bar:
    def __init__(self):
        self._param = 0
    @property
    def param(self):
        return self._param
    @param.setter
    def param(self, param):
        self._param = param

@delegate('v', 'param')
class Foo2:
    def __init__(self):
        self.v = Bar()

foo2 = Foo2()
foo2.param  # => 0

foo2.param = 2
foo2.param  # => 2
foo2.v.param   # => 2
foo2.v._param   # => 2

Running tests

Simply run the module python -m delegateto

Metadata

Release files for delegateto 1.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for delegateto 1.5
File Size Uploaded
delegateto-1.5.tar.gz 3.6 kB Details

Release files / delegateto-1.5.tar.gz

Download URL delegateto-1.5.tar.gz
Size 3.6 kB
Tags Source
SHA-256 checksum
How to use checksums
914050706afd9d4edbd0bac16d56615d60d043e2b64c4898b29721ec9da5f686
BLAKE2b-256 checksum
How to use checksums
d19997690bafaef432ef9aba80219328fd232fe619ccdf293a306cbd3c4cf298
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/42.0.2 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.7.6

Release history Release notifications | RSS feed

This release

1.5 This release

1 release file

1.4

1 release file

1.3

2 release files

1.2

2 release files

1.1

2 release files

1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page