473,734 Members | 2,211 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Finding defining class in a decorator

We have a tracing decorator that automatically logs enter/exits to/from
functions and methods and it also figures out by itself the function
call arguments values and the class or module the function/method is
defined on. Finding the name of the class where the method we just
entered was defined in is a bit tricky.

Here's a snippet of the test code:

class Base:
@tracelevel(1)
def foomethod(self, x, y=5, **kwds):
return x+y

class TClass(Base):
@tracelevel(1)
def foomethod(self, x, y=1, **kwds):
return Base.foomethod( self, x, **kwds) + x + y

t = TClass()
t.foomethod(4, d=1)
return

The output format is irrelevant at this point but it should be
something like:

TClass:foometho d ...
Base:foomethod ...

correctly showing the name of the class where the entered method was
defined on.

We are also using the proposed decorator function in the future
functools module, which looks like this:

def _update_wrapper (decorated, func, deco_func):
# Support naive introspection
decorated.__mod ule__ = func.__module__
decorated.__nam e__ = func.__name__
decorated.__doc __ = func.__doc__
decorated.__dic t__.update(func .__dict__)
decorated.__dec orator__ = deco_func
decorated.__dec orates__ = func

def decorator(deco_ func):
"""Wrap a function as an introspection friendly decorator
function"""
def wrapper(func):
decorated = deco_func(func)
if decorated is func:
return func
_update_wrapper (decorated, func, deco_func)
return decorated
# Manually make this decorator introspection friendly
_update_wrapper (wrapper, deco_func, functools_decor ator)
return wrapper

In our decorator, the part that figures out the name of the class where
the wrapped method was defined in has to start with the assumption that
the first argument is self and then find the defining class from it.
This code fragment is in the wrapper function of the decorator:

if numargs > 0:
# at definition time, class methods are not methods
# yet because the class doesn't exist when the
# decorators get called and thus, we have to figure
# out classname at runtime via self
#
# assume first arg is self, see if f.__name__ is there
# as a method and if so, then grab it's class name
#
self = args[0]
if type(self) == types.InstanceT ype:
# getattr will find the method anywhere in the
# class tree so start from the top
bases = list(inspect.ge tmro(self.__cla ss__))
bases.reverse()
for c in bases:
# f was given to us in the deco_func
meth = getattr(c, f.__name__, None)

# we found a method with that name, which
# it's probably this same wrapper function
# we used to wrap the original method with.

ofunc = getattr(meth, '__decorates__' , False)

if ofunc and ofunc.func_code == f.func_code:
# got it
clsname = meth.im_class._ _name__
break

Is there a way to do this without the __decorates__ attribute?

--
Luis P Caamano
Atlanta, GA, USA

May 10 '06 #1
2 1499
lcaamano wrote:
We have a tracing decorator that automatically logs enter/exits to/from
functions and methods and it also figures out by itself the function
call arguments values and the class or module the function/method is
defined on. Finding the name of the class where the method we just
entered was defined in is a bit tricky.
[snipped]

You might find this helpful:

import sys

def tracer(func):
"""
A decorator that prints the name of the class from which it was
called.

The name is determined at class creation time. This works
only in CPython, since it relies on the sys._getframe()
function. The assumption is that it can only be called
from a class statement. The name of the class is deduced
from the code object name.
"""
classframe = sys._getframe(1 )
print classframe.f_co de.co_name
return func
if __name__ == '__main__':

# this should print Test1

class Test1(object):

@tracer
def spam(self):
pass

# this should print Test2

class Test2(Test1):

@tracer
def spam(self):
pass

--
Luis P Caamano
Atlanta, GA, USA


Hope this helps,
Ziga

May 10 '06 #2
Nice. I had to call _getframe(2) to account for the wrapper but the
idea seems to work OK, that is, save the name of the decorator's
original caller at definition time while creating the wrapper function.
Much better than doing that at runtime.

Thanks

--
Luis P Caamano
Atlanta, GA USA

May 10 '06 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
1570
by: Humpty Dumpty | last post by:
Hello, I'm experimenting with different ways of extending a class (for a plug-ins framework for a GUI) with more than one extension when some of these extensions need to collaborate, but others mustn't know about each other. I.e., if I have a class A, and I want to add a block of functionality, I can derive it into a B that adds that fucntionality. If I want to add more functionality, I can derive B into a C. But if I want to add a...
22
2233
by: Ron_Adam | last post by:
Hi, Thanks again for all the helping me understand the details of decorators. I put together a class to create decorators that could make them a lot easier to use. It still has a few glitches in it that needs to be addressed. (1) The test for the 'function' object needs to not test for a string but an object type instead.
19
420
by: Kirk Strauser | last post by:
Given a class: how can I find its name, such as: 'foo' I'm writing a trace() decorator for the sake of practice, and am trying to print the name of the class that a traced method belongs to. This seems like it should be easy, but I think I've been staring at the problem too
6
1839
by: MattWilson.6185 | last post by:
Hi, I'm trying to find out if something is possible, I have a few diffrent lists that I add objects to and I would like to be able to have a wrapper class that won't affect the internal object, for instnace class base { }; class a : public base { };
0
2831
by: emin.shopper | last post by:
I had a need recently to check if my subclasses properly implemented the desired interface and wished that I could use something like an abstract base class in python. After reading up on metaclass magic, I wrote the following module. It is mainly useful as a light weight tool to help programmers catch mistakes at definition time (e.g., forgetting to implement a method required by the given interface). This is handy when unit tests or...
6
3418
by: Chris Fonnesbeck | last post by:
I have a class that does MCMC sampling (Python 2.5) that uses decorators -- one in particular called _add_to_post that appends the output of the decorated method to a class attribute. However, when I subclass this base class, the decorator no longer works: Traceback (most recent call last): File "/Users/chris/Projects/CMR/closed.py", line 132, in <module> class M0(MetropolisHastings): File "/Users/chris/Projects/CMR/closed.py", line...
5
1292
by: Nathan Harmston | last post by:
HI, I m trying to start an api in a similar way to the djangic way of Class.objects.all(). Ie objects is a "Manager" class. So: class Foo(object): def __init__(self): self.test = "NEE"
2
1951
by: Andrew West | last post by:
Probably a bit of weird question. I realise decorators shouldn't be executed until the function they are defined with are called, but is there anyway for me to find all the decorates declared in a file when I import it? Or perhaps anyway to find the decorators by loading the file by other methods (with out simply parsing it by hand). Basically what I'm looking for is a way to, given a python file, look through that file and find all the...
4
1617
by: Wilbert Berendsen | last post by:
Hi, is it possible to manipulate class attributes from within a decorator while the class is being defined? I want to register methods with some additional values in a class attribute. But I can't get a decorator to change a class attribute while the class is still being defined. Something like: class Parser(object): regexps =
0
8776
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9310
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9236
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9182
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6735
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6031
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4550
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4809
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
2724
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.