Mo J. Mughrabi
Mo J. Mughrabi

Reputation: 6997

creating method signals to automatically fire up on an event in python

I don't honestly know if such thing exists or not, but I tried to do some research and ended up getting confused with something called d-Bus and not sure if that's what am looking for here,

class BigClass(Object):
  def Foo(self):
     print 'calling foo'

  def Logger(self):
     print 'foo has been called'

a = BigClass()
a.foo()

what am trying to do here is invoke Logger() method when foo() is being called. I want to create some sort of a event/signal where it will fire up logger() when specific methods are called in my class or all methods.

Upvotes: 1

Views: 221

Answers (2)

Jonathan Eunice
Jonathan Eunice

Reputation: 22443

While an explicit logging call (or logging decorator, as warwaruk suggests) is the most straightforward approach, it is possible to automate logging, if you're willing to play a naming trick such as having the logical foo method be implemented by Foo. Python is case-sensitive, so those are separate and distinct. Then implement a __getattr__ method, like so:

class AutoLogger(object):

    def __getattr__(self, attr):
        try:
            return self.__class__.__dict__[attr]
        except KeyError:
            func = self.__class__.__dict__[attr.capitalize()]
            return lambda *args, **kwargs: self.log_call(attr, func, *args, **kwargs)

    def log_call(self, func_name, func, *args, **kwargs):
        func(self, *args, **kwargs)
        print func_name, 'has been called (handled by', func_name.capitalize() + ')'

class BigAutoLoggerClass(AutoLogger):
    def Foo(self):
        print 'calling Foo'


b = BigAutoLoggerClass()
b.Foo()
print "---"
b.foo()

This yields:

calling Foo
---
calling Foo
foo has been called (handled by Foo)

bar would similarly be implemented by Bar, and so on.

If you don't like this naming slight-of-hand, logging can also be automated via the sys.settrace() function. That, however, adds a lot of run-time overhead and is really only suited for debugging or situations where low(ish) performance is okay.

Upvotes: 0

warvariuc
warvariuc

Reputation: 59594

I don't know your particular situation, but there is a good signal/callback lib called dispatch: http://pydispatcher.sourceforge.net/

But i prefer using Django dispatcher which was created based on PyDispatcher, but signal creation is more intuitive: https://github.com/django/django/blob/master/django/dispatch/dispatcher.py

what am trying to do here is invoke Logger() method when foo() is being called. I want to create some sort of a event/signal where it will fire up logger() when specific methods are called in my class or all methods.

Why don't you then call Logger method manually from foo method? Or better make a decorator to use it like:

class BigClass(Object):

  def Logger(self):
     print 'foo has been called'

  @log(Logger)
  def Foo(self):
     print 'calling foo'


a = BigClass()
a.foo()

Upvotes: 2

Related Questions