[Tutor] Importing from classes or functions
Danny Yoo
dyoo at hkn.eecs.berkeley.edu
Thu Oct 30 20:46:39 EST 2003
> > 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.
Hi Daniel,
Let's go back for a moment. The situation is simliar to something like
this:
###
class TestScope1:
def __init__(self):
x = 42
def test(self):
print x
###
This breaks with a familiar "NameError" exception because, in test(),
Python has no idea what 'x' means. So the reason TestScope1 breaks is the
same reason that:
###
class sinnum(int):
def __init__(s, number):
import math
s.num = number
def sin(s):
return math.sin(s)
###
breaks.
If we actually wanted to squirrel the value as part of the state of that
TestScope1 instance, we can say something like:
###
class TestScope1_fixed:
def __init__(self):
self.x = 42
def test(self):
print self.x
###
and we can fix sinnum() by using a similar approach.
> Someone else on the list suggested using the __import__ function (not
> definition, just using the function), and it worked.
True. But there's nothing special about __import__(). Compare the
__import__() example with:
###
class sinnum(int):
def __init__(self, number):
self.num = number
import math
self.math = math
def sin(self):
return self.math.sin(self)
###
Does that make sense? Please feel free to ask questions about this, as
variable name scope is a useful concept.
I'm actively trying to ignore the first part of your question:
> > >>> class sinnum(int):
> > ... def __getattr__(self, attr):
> > ... def f(*args):
> > ... return apply(getattr(__builtins__,
> > attr),
> > ... (self,) + args)
> > ... return f
> > ###
> >
> 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.
because I haven't figured out how to explain it well yet. *grin*
Talk to you later!
More information about the Tutor
mailing list