unexpected from/import statement behaviour

Peter Otten __peter__ at web.de
Wed Aug 27 15:35:13 CEST 2008


nisp wrote:

> Thanks first of all ! I read the interesting Diez's link but something
> still remains to me unclear, on the other hand it's clear the my
> problem is concentrated there and on symbols.

Read it again. If you have two modules

module1.py
from sys import stderr

module2.py
from module1 import stderr

you get three names 'stderr' in three different namespaces, and each name
may bind a different object.


> Here is what I'm trying to do
> 
> HelloWorld.py: this is a real simplification of my external module
> though still reflecting its structure (commented out is the version
> that, let's say, works)
> 
> from sys import stderr
> #import sys
> 
> class Cheers:
>         def __init__(self):
>                 self.cheersMsg = 'Hello World !!'
>                 print "Cheers stderr %s" % stderr
>                 #print "Cheers stderr %s" % sys.stderr
>         def _putCheers(self):
>                 print>>stderr, 'Here is my msg:', self.cheersMsg
>                 print>>stderr, 'This is a nice day today !!'
>                 #print>>sys.stderr, 'Here is my msg:', self.cheersMsg
>                 #print>>sys.stderr, 'This is a nice day today !!'
>         def doSomeStuff(self):
>                 self._putCheers()
> 
> And below there is the module that uses the above one (mymodule.py):
> 
> #!/usr/bin/python
> 
> import sys

This imports HelloWorld.stderr:

> from HelloWorld import *

You now have a global variable 'stderr' in module __main__, initialized to
the same value as HelloWorld.stderr.

> class StderrCatcher:
>         def __init__(self):
>                 self.data = ''
>         def write(self,stuff):
>                 self.data = self.data + "\t" + stuff
> 
> 
> def main():
> 
>         print "mymodule stderr: %s" % sys.stderr
> 

This rebinds sys.stderr and a local 'stderr' in main()

>         sys.stderr = stderr = StderrCatcher()

but both HelloWorld.stderr and __main__.stderr are unaffected. What you need
is
          import HelloWorld
          sys.stderr = HelloWorld.stderr = StderrCatcher()

>         m = Cheers()
>         m.doSomeStuff()
>         print "stderr: \n%s" % sys.stderr.data
> 
> if __name__ == '__main__':
>     main()
> 
> 
> Below there is the output when it doesn't work:
> 
> mymodule stderr: <open file '<stderr>', mode 'w' at 0xb7d160b0>
> Cheers stderr <open file '<stderr>', mode 'w' at 0xb7d160b0>
> Here is my msg: Hello World !!
> This is a nice day today !!
> stderr:
> 
> And here when it works:
> 
> mymodule stderr: <open file '<stderr>', mode 'w' at 0xb7dc40b0>
> Cheers stderr <__main__.StderrCatcher instance at 0xb7d8bd4c>
> stderr:
>         Here is my msg:         Hello World !!
>         This is a nice day today !!
> 
> 
> Thanks again!
> 
> PS Sorry for having probably replied to somone of you directly :-(



More information about the Python-list mailing list