Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > How can a function find the function that called it?

Reply
Thread Tools

How can a function find the function that called it?

 
 
kj
Guest
Posts: n/a
 
      12-24-2010





I want to implement a frozen and ordered dict.

I thought I'd implement it as a subclass of collections.OrderedDict
that prohibits all modifications to the dictionary after it has
been initialized.

In particular, calling this frozen subclass's update method should,
in general, trigger an exception ("object is not mutable").

But OrderedDict's functionality *requires* that its __init__ be
run, and this __init__, in turn, does part of its initialization
by calling the update method.

Therefore, the update method of the new subclass needs to be able
to identify the calling function in order to make a special allowance
for calls coming from OrderedDict.__init__. (Better yet, it should
be able to allow calls coming from its own class's __init__, via
OrderedDict.__init__.)

The best I've been able to do is to use inspect to get the name of
the calling function. For the case I'm trying to identify, this
name is simply "__init__".

But Python code is awash in __init__'s...

Is it possible to achieve a more precise identification? Specifically,
I want to know the *class* (not the file) where this '__init__' is
defined.

(BTW, I don't understand why inspect doesn't provide something as
basic as the *class* that the method belongs to, whenever applicable.
I imagine there's a good reason for this coyness, but I can't figure
it out.)

TIA!

~kj

 
Reply With Quote
 
 
 
 
Chris Gonnerman
Guest
Posts: n/a
 
      12-24-2010
On 12/24/2010 10:24 AM, kj wrote:
> I want to implement a frozen and ordered dict.
>
> I thought I'd implement it as a subclass of collections.OrderedDict
> that prohibits all modifications to the dictionary after it has
> been initialized.
>
> In particular, calling this frozen subclass's update method should,
> in general, trigger an exception ("object is not mutable").
>
> But OrderedDict's functionality *requires* that its __init__ be
> run, and this __init__, in turn, does part of its initialization
> by calling the update method.

Use a flag, "private" to your new class, to indicate whether
initialization is complete or not; your update method would see that
initialization is not yet complete when called by __init__, and so it
would do its business (calling the class method). At the end of the
__init__ function, set the initialized property to true. If your update
is called with the initialized property already set to true, it will
raise the exception.

 
Reply With Quote
 
 
 
 
ChasBrown
Guest
Posts: n/a
 
      12-24-2010
On Dec 24, 8:24*am, kj <(E-Mail Removed)> wrote:
> I want to implement a frozen and ordered dict.
>
> I thought I'd implement it as a subclass of collections.OrderedDict
> that prohibits all modifications to the dictionary after it has
> been initialized.
>
> In particular, calling this frozen subclass's update method should,
> in general, trigger an exception ("object is not mutable").
>
> But OrderedDict's functionality *requires* that its __init__ be
> run, and this __init__, in turn, does part of its initialization
> by calling the update method.
>


Rather than trying to identify the caller, I'd do something like:

class FrozenODict(OrderedDict):

def __init__(self, *args, **kwargs):
OrderedDict.__init__(self, *args, **kwargs)
self.update = self._update # init is complete, so override
# update method for this instance

def _update(self, dict2):
raise Exception("object is immutable!!")

After the __init__, calls to the instance's 'update' function will be
mapped to _update. It's essentially overriding the inherited function
on the fly.

Cheers - Chas

 
Reply With Quote
 
Daniel Urban
Guest
Posts: n/a
 
      12-24-2010
On Fri, Dec 24, 2010 at 17:24, kj <(E-Mail Removed)> wrote:
> (BTW, I don't understand why inspect doesn't provide something as
> basic as the *class* that the method belongs to, whenever applicable.
> I imagine there's a good reason for this coyness, but I can't figure
> it out.)


One function object can "belong to" (be in the namespace of) more than
one class, so there is no "the class".
 
Reply With Quote
 
John Nagle
Guest
Posts: n/a
 
      12-24-2010
On 12/24/2010 8:51 AM, Chris Gonnerman wrote:
> On 12/24/2010 10:24 AM, kj wrote:
>> I want to implement a frozen and ordered dict.
>>
>> I thought I'd implement it as a subclass of collections.OrderedDict
>> that prohibits all modifications to the dictionary after it has
>> been initialized.


That's actually a fairly common question - is an object in
initialization, or has it been fully created? It would be useful
if Python had some standard way to check if initialization
has completed. Sometimes a parent class needs to know if
initialization of the entire object has completed. This typically
comes up with classes that define "__setattr__" and are then
subclassed.


John Nagle
 
Reply With Quote
 
kj
Guest
Posts: n/a
 
      12-24-2010
In <(E-Mail Removed)> Daniel Urban <(E-Mail Removed)> writes:

>On Fri, Dec 24, 2010 at 17:24, kj <(E-Mail Removed)> wrote:
>> (BTW, I don't understand why inspect doesn't provide something as
>> basic as the *class* that the method belongs to, whenever applicable.
>> I imagine there's a good reason for this coyness, but I can't figure
>> it out.)


>One function object can "belong to" (be in the namespace of) more than
>one class, so there is no "the class".


There are many other properties that inspect reports on (e.g.
filename) that may not apply to an individual case. For 99.9% of
methods, the class in which it was lexically defined would be good
enough.
 
Reply With Quote
 
Mark Wooding
Guest
Posts: n/a
 
      12-24-2010
kj <(E-Mail Removed)> writes:

> But OrderedDict's functionality *requires* that its __init__ be
> run, and this __init__, in turn, does part of its initialization
> by calling the update method.
>
> Therefore, the update method of the new subclass needs to be able
> to identify the calling function in order to make a special allowance
> for calls coming from OrderedDict.__init__


That doesn't follow at all. Why not set a `frozen' flag when your
initialization is complete? Something like

class ImmutableOrderedDict (OrderedDict):
def __init__(me, *args, **kw):
me._frozen = False
OrderedDict.__init__(me, *arg, **kw)
me._frozen = True
def _check(me):
if me._frozen:
raise ImmutableError

And so on.

Thank you for explaining your actual objective, by the way.

-- [mdw]
 
Reply With Quote
 
DevPlayer
Guest
Posts: n/a
 
      12-25-2010
> Original Poster
> I thought I'd implement it as a subclass of collections.OrderedDict
> that prohibits all modifications to the dictionary after it has
> been initialized.


I thought the __new__() method was for customizing how objects where
instantated. Where in __new__() you would get an object instance and
then usually initialize the public data attributes in __init__().
Although I like Mark Wooding's solution as it's clean and easy to
understand.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
problem in running a basic code in python 3.3.0 that includes HTML file Satabdi Mukherjee Python 1 04-04-2013 07:48 PM
Why is a button Click event also called when a textbox TextChanged event is called??? S_K ASP .Net 6 11-08-2007 07:44 PM
What is called carry chain structure in FPGA is called in IC? Weng Tianxiang VHDL 6 09-12-2007 07:19 AM
three times copy ctor called, one ctor called, why? Apricot C++ 4 04-16-2004 07:55 AM



Advertisments