Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Best way to dynamically get an attribute from a module from withinthe same module

Reply
Thread Tools

Best way to dynamically get an attribute from a module from withinthe same module

 
 
Rafe
Guest
Posts: n/a
 
      11-24-2008
What are the pros and cons of these two patterns (and are there any
other)? Which is the best way to dynamically get an attribute from a
module from within the same module?

1) Using the name of the module
this_module = sys.modules[__name__]
attr = getattr(this_module, "whatever", None)

2) using globals
globals()["whatever"]


I have been using #1 for two reasons. First, I will never run this
module directly, so __name__ will always be the module name and not
"__main__". Second, I can use this in a class to decide whether I want
the module where the class came from or, if I make the class a base
for a class in another module, the module where the sub-class is.

I am not familiar with the scope, pros or cons of globals() so I would
love to hear comments on this subject.


Cheers,

- Rafe
 
Reply With Quote
 
 
 
 
Gabriel Genellina
Guest
Posts: n/a
 
      11-29-2008
En Mon, 24 Nov 2008 02:11:49 -0200, Rafe <(E-Mail Removed)> escribió:

> What are the pros and cons of these two patterns (and are there any
> other)? Which is the best way to dynamically get an attribute from a
> module from within the same module?
>
> 1) Using the name of the module
> this_module = sys.modules[__name__]
> attr = getattr(this_module, "whatever", None)
>
> 2) using globals
> globals()["whatever"]


3) using the bare name:
whatever

1) and 2) are useful when the desired name is variable, not a constant
like "whatever".

> I have been using #1 for two reasons. First, I will never run this
> module directly, so __name__ will always be the module name and not
> "__main__".


(note that it works even with __main__)

> Second, I can use this in a class to decide whether I want
> the module where the class came from or, if I make the class a base
> for a class in another module, the module where the sub-class is.


I don't completely understand your use case. In the expression:
getattr(some_module, attribute_name)
you may use any module as the first argument (the current module, or any
other).

> I am not familiar with the scope, pros or cons of globals() so I would
> love to hear comments on this subject.


Perhaps if you explain in more detail your use case, somebody else may
have further comments...
I don't have the need to use globals()[name] very often.

--
Gabriel Genellina

 
Reply With Quote
 
 
 
 
Rafe
Guest
Posts: n/a
 
      12-01-2008
<snip>
> 3) using the bare name:
> whatever
> 1) and 2) are useful when the desired name is variable, not a constant like "whatever".


I thought that went without saying.


> > I have been using #1 for two reasons. First, I will never run this
> > module directly, so __name__ will always be the module name and not "__main__".

>
> (note that it works even with __main__)


Nice. Thanks.

> > Second, I can use this in a class to decide whether I want
> > the module where the class came from or, if I make the class a base

> I don't completely understand your use case. In the expression:
> * * getattr(some_module, attribute_name)
> you may use any module as the first argument (the current module, or any other).


Right, I was just confused about the effects of inheritance and scope.
If I put a method in a baseclass, which is inherited in another
module, and then run the method from an instance of the sub-class...

- "sys.modules[__name__]" returns the baseclass module.

- "sys.modules[self.__class__.__module__]" returns the subclass
module.

in the end I found it felt more logical to put the code in a module-
level function and call it from the class. All of this was part of a
fairly large factory method implementation.


I now know that globals() refers to module-level names. The pros and
cons were the main point of this thread and so far I have...

1) getattr(module, "whatever") seems the most pythonic way to do it
but it takes more than one line and requires a little more thought
about scope and inheritance.

2) globals()["whatever"] is concise, but it seems a little like a
shortcut which requires special knowledge (though a very small
amount).

I did a quick benchmark test:
< tmp2.py >
import time
import sys

import tmp

class A(tmp.A): pass
class B(tmp.A): pass
class C(tmp.A): pass
class D(tmp.A): pass
class E(tmp.A): pass
class F(tmp.A): pass
class G(tmp.A): pass
class H(tmp.A): pass
class I(tmp.A): pass
class J(tmp.A): pass


def test_globals_vs_gettattr():
t1 = time.time()
for i in range(0, 1000000):
H = globals()["H"]
t2 = time.time()
print "globals() too %s seconds." % str(t2-t1)

t1 = time.time()
mod = sys.modules[__name__]
for i in range(0, 1000000):
H = getattr(mod, "H")
t2 = time.time()
print "getattr() too %s seconds." % str(t2-t1)
< /tmp2.py >

tmp.py just has a simple class in it. I just wanted to add some
complexity, but I doubt this had any affect on the times.

>>> import tmp2
>>> tmp2.test_globals_vs_gettattr()

globals() too .146900010109 seconds.
getattr() too .434299993515 seconds.


Just to see how much the call to sys.modules was affecting the test, I
moved it outside the loop and reloaded the module for a second test.
>>> reload(tmp2)

<module 'tmp2' from '\\nas6tb\PROJECTS\tech\users\rafe.sacks\python
\tmp2.py'>
>>> tmp2.test_globals_vs_gettattr()

globals() too .139100003242 seconds.
getattr() too .254600000381 seconds.

This second test is pointless in practice since I would be calling
sys.modules each time anyway.

Even though the getattr() way is around 3.5 times slower, I had to run
the code 1,000,000 times before the difference became humanly
recognizable. I also realize benchmarks should be taken with a grain
of salt since my setup may differ greatly from others'.

I guess, in the end, I'd use getattr() because it feels more pythonic,
and more basic. I got pretty deep in to learning python before I had
to learn what the globals() dict could do for me.


Cheers,

- Rafe
 
Reply With Quote
 
Jeremy Sanders
Guest
Posts: n/a
 
      12-01-2008
Rafe wrote:

> I guess, in the end, I'd use getattr() because it feels more pythonic,
> and more basic. I got pretty deep in to learning python before I had
> to learn what the globals() dict could do for me.


Why not store your individual classes inside another class or keep them in a
dict? That would be clearer, would not mess around with global namespace,
and more pythonic IMHO.

Jeremy

--
Jeremy Sanders
http://www.jeremysanders.net/
 
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
Best way to do attribute docstrings? Ken Kuhlman Python 5 09-27-2007 03:26 AM
JNDI: Delete only one attribute when there are several different values for the same attribute bsporb@gmail.com Java 3 05-02-2007 05:41 AM
ATTRIBUTE ERROR: 'module' object has no attribute 'ssl' johnny Python 5 12-10-2006 01:10 PM
what the best way to get 1000 page on same server? JuHui Python 0 03-18-2006 12:37 PM
Best way to control assignment to attribute? Frank Millman Python 7 02-05-2004 07:34 AM



Advertisments