Skip to main content

Observer pattern for functions and bound methods

Project description

observed allows you to to sign up functions or methods to "observe" other functions or methods:

from observed import observable_function

@observable_function
def observed_func(arg):
    print("observed_func: %s"%(arg,))

def observer_func(arg):
    print("observer_func: %s"%(arg,))

observed_func.add_observer(observer_func)
observed_func('banana')

>>> observed_func: banana
>>> observer_func: banana

You can also register observers for bound methods:

from observed import observable_method

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

    @observable_method()
    def bar(self, arg):
        print("Object %s invoked bar with arg='%s'"%(self.name, arg))

    def baz(self, arg):
        print("Object %s invoked baz with arg='%s'"%(self.name, arg))

def callback(arg):
    print("callback was invoked with arg='%s'"%(arg,))

a = Foo('a')
b = Foo('b')
a.bar.add_observer(b.bar)
a.bar.add_observer(b.baz)
a.bar.add_observer(callback)
a.bar('banana')

>>> Object a invoked bar with arg='banana'
>>> Object b invoked bar with arg='banana'
>>> Object b invoked baz with arg='banana'
>>> callback was invoked with arg='banana'

You can ask that the observed object pass itself as the first argument whenever it calls observers:

from observed import observable_function

@observable_function
def observed_func():
    print("observed_func: I was called")

def observer_func(observed):
    print("observer_func: %s called me"%(observed.__name__,))

observed_func.add_observer(observer_func, identify_observed=True)
observed_func()

>>> observed_func: I was called
>>> observer_func: observed_func called me

When observed bound methods pass themselves as the observed object, keep in mind that you can always access the associated instance via __self__:

from observed import observable_method

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

    @observable_method()
    def bar(self):
        print("Object %s invoked bar"%(self.name,))

def callback(observed):
    print("callback was invoked by='%s'"%(observed.__self__.name,))

a = Foo('a')
a.bar.add_observer(callback, identify_observed=True)
a.bar()

>>> Object a invoked bar
>>> callback was invoked by a

Notable features include:

  • A function or bound method is not kept alive just because it is observing something else. This is because the observed object does not keep any strong references to the observing objects. In CPython this means that your observers are automatically detached whenever the reference count to that observer goes to zero.

  • The observable_method decorator can be used on methods in classes which are unhashable types, and can be used on an arbitrary number of methods in each class...

  • ...but the descriptor which handles observable_method does not paste any data onto the instances it manages. There is zero chance of name collision on the observed instances.

Installation

observed exists on the python package index, so you can do pip install observed to install it. Alternatively, you can download the source distribution and in the root directory of the distribution do

$ python setup.py install

News

See the file NEWS for the user-visible changes from previous releases.

License

See LICENSE.txt.

Downloading

observed can be obtained from the python package index at or via GitHub.

Documentation

Basic usage is illustrated at the top of this file. Further examples are given in example.py.

Development

observed development is hosted on github. The current working repository is given in the Downloading section above.

Bug Reporting

Please submit bug tickets on the GitHub tracking system.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

observed-0.5.1.tar.gz (3.0 kB view details)

Uploaded Source

Built Distribution

observed-0.5.1-py2.py3-none-any.whl (3.3 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file observed-0.5.1.tar.gz.

File metadata

  • Download URL: observed-0.5.1.tar.gz
  • Upload date:
  • Size: 3.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.1 CPython/3.6.5

File hashes

Hashes for observed-0.5.1.tar.gz
Algorithm Hash digest
SHA256 d16d0808215a1eb051d04d4ee42d91c3890141a9c7d3af692be018a4e534214a
MD5 a1bf017ae0cc4e0edbd3e447bed98209
BLAKE2b-256 ea4b1d01f310c1fb566372de57e9e529ccc5f3e64a2cb14c24edfb42cf5d31c2

See more details on using hashes here.

File details

Details for the file observed-0.5.1-py2.py3-none-any.whl.

File metadata

  • Download URL: observed-0.5.1-py2.py3-none-any.whl
  • Upload date:
  • Size: 3.3 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.1 CPython/3.6.5

File hashes

Hashes for observed-0.5.1-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 36d19fe3a22ece8b474e5a3753728ae51c00b122d57ff9f1782bd7f3ae640733
MD5 23a0b7a6de1e54f6a9452f8a078289a6
BLAKE2b-256 e7dca2b9436e76cc639a01cc77ffa3c4a450d1dd03df73b8354cdfd79d34b032

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page