tags:

views:

173

answers:

3

Suppose you have 3 modules, a.py, b.py, and c.py:

a.py:

v1 = 1
v2 = 2
etc.

b.py:

from a import *

c.py:

from a import *
v1 = 0

Will c.py change v1 in a.py and b.py? If not, is there a way to do it?

+1  A: 

Yes, you just need to access it correctly (and don't use import *, it's evil)

c.py:

import a
print a.v1 # prints 1
a.v1 = 0
print a.v1 # prints 0
zepolen
+2  A: 

The from ... import * form is basically intended for handy interactive use at the interpreter prompt: you'd be well advised to never use it in other situations, as it will give you nothing but problems.

In fact, the in-house style guide at my employer goes further, recommending to always import a module, never contents from within a module (a module from within a package is OK and in fact recommended). As a result, in our codebase, references to imported things are always qualified names (themod.thething) and never barenames (which always refer to builtin, globals of this same module, or locals); this makes the code much clearer and more readable and avoids all kinds of subtle anomalies.

Of course, if a module's name is too long, an as clause in the import, to give it a shorter and handier alias for the purposes of the importing module, is fine. But, with your one-letter module names, that won't be needed;-).

So, if you follow the guideline and always import the module (and not things from inside it), c.v1 will always be referring to the same thing as a.v1 and b.v1, both for getting AND setting: here's one potential subtle anomaly avoided right off the bat!-)

Remember the very last bit of the Zen of Python (do import this at the interpreter prompt to see it all):

Namespaces are one honking great idea -- let's do more of those!

Importing the whole module (not bits and pieces from within it) preserves its integrity as a namespace, as does always referring to things inside the imported module by qualified (dotted) names. It's one honking great idea: do more of that!-)

Alex Martelli
So you never "from datetime import datetime"; you always import datetime, and type "datetime.datetime" every time? That's a terrible style guide.
Glenn Maynard
@Glenn, to your question, "yes"; to your opinion, I don't know of any Python style guide actively accepted (and enforced, via "readability reviews") by more Python committers (including Guido;-), AND our Python SW seems to be reasonably successful (including time to market, maintainability, performance [cfr YouTube, Python-based AND fast], etc), so I wonder on what empirical data you base that opinion. Yep, PEP 8 does accept "importing a class", but Guido wrote that _before_ he joined Google and met (and accepted, and enforced) our awesome style guide!-)
Alex Martelli
Writing "datetime.datetime" is terribly ugly; "datetime.datetime.now" is even uglier; coding styles that encourage ugly code are bad. More broadly, having the module as a namespace is simply unhelpful when the class itself is a namespace. Import the level which is intended as a namespace--for many modules, that's the module itself, but for classes like datetime, it's the class.
Glenn Maynard
+5  A: 

All that a statement like:

v1 = 0

can do is bind the name v1 to the object 0. It can't affect a different module.

If I'm using unfamiliar terms there, and I guess I probably am, I strongly recommend you read Fredrik Lundh's excellent article Python Objects: Reset your brain.

RichieHindle