[Tutor] Importing from classes or functions

Daniel Ehrenberg littledanehren at yahoo.com
Thu Oct 30 19:42:13 EST 2003


> Yes, it's possible to do something like this, if we
> do some attribute
> lookup trickery:
> 
> ###
> >>> class sinnum(int):
> ...     def __getattr__(self, attr):
> ...         def f(*args):
> ...             return apply(getattr(__builtins__,
> attr),
> ...                          (self,) + args)
> ...         return f
> ...
> >>> x = sinnum(5)
> >>> x.abs()
> 5
> >>> x = sinnum(-5)
> >>> x.abs()
> 5
> ###
> 
Would you mind explaining that code? I can't
understand it, and it doesn't seem to work if you're
using namespaces. I'd like it to work so that the math
module is imported locally and math functions can be
used without namespaces.

> 
> So it's sorta working.  But this isn't quite right,
> though:
> 
> ###
> >>> x.abs().abs()
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
> AttributeError: 'int' object has no attribute 'abs'
> ###
> 
> The error here shows that the definition above isn't
> providing "closure",
> in the sense that the value of 'x.abs()' isn't a
> Ruby-style "sinnum", so
> we can't compose two operations, like:
> 
>     x.abs.abs()
> 
> 
> Anyway, once we see this, we can fix this problem:
> 
> ###
> >>> class sinnum(int):
> ...     def __getattr__(self, attr):
> ...         def f(*args):
> ...             return
> sinnum(apply(getattr(__builtins__, attr),
> ...                                 (self,) + args))
> ...         return f
> ...
> >>> x = sinnum(42)
> >>> x.pow(2).pow(2)
> 3111696
> ###
> 
> 
> 
I don't see the difference between those two classes.
> 
> > I wanted to import it within the class, since when
> I'm finished, the
> > module should contain more than one datatype (an
> extended int, an
> > extended float, an extended string, etc). But when
> I try to impliment
> > importing within the class, the import doesn't
> work.
> 
> Think of 'import math' as a statement that creates a
> local variable called
> 'math'.  Then the error message should be less
> mysterious:
> 
> 
> > >>> class sinnum(int):
> > ...     def __init__(s, number):
> > ...         import math
> > ...         s.num = number
> > ...     def sin(s):
> > ...         return math.sin(s)
> > ...
> > >>> x = sinnum(5)
> > >>> x.sin()
> > Traceback (most recent call last):
> >   File "<input>", line 1, in ?
> >   File "<input>", line 6, in sin
> > NameError: global name 'math' is not defined
> 
> 
> 'math' here is a local variable within __init__, so
> it won't be visible
> from the 'sin()' function.  So the error is actually
> not too serious: it's
> a scope issue.
> 

No, when I tried importing math outside of the
__init__ function, it didn't do anything. Someone else
on the list suggested using the __import__ function
(not definition, just using the function), and it
worked.
> 
> 
> To tell the truth, I think it might be a bad idea in
> Python.  *grin*
> 
> 
> It's probably not outrageously inefficient --- all
> Python method access is
> done through attribute lookup anyway --- but it's
> just something that most
> Python programmers won't recognize at first.

So you're saying it's a bad idea because people won't
recognize it at first? Well, I guess I'll just make it
for my personal use, then.
Daniel Ehrenberg

__________________________________
Do you Yahoo!?
Exclusive Video Premiere - Britney Spears
http://launch.yahoo.com/promos/britneyspears/



More information about the Tutor mailing list