views:

81

answers:

4

from here I got an idea about how using variables from other modules. this all works fine with

import foo as bar

But I don't want to import my modules as "bar" I want to use it without any prefix like

from foo import *

Using this it´s impossible to modify variables from other modules. reading will work! any idea? suggestions?

A: 

By using import foo from bar you don't import bar as a variable but as a constant.

+1  A: 

As far as I know, there is no way to import a value from a module and have it readable and writable by the importing scope. When you just import foo in Python, it creates a module object named foo. Getting and setting attributes on a module object will change them in the module's scope. But when you from foo import something, foo is imported and a module object is created, but is not returned. Instead, Python copies the values you specified out of foo and puts them in the local scope. If what you are importing is an immutable type like int or str, then changing it and having the changes reflect in the foo module is impossible. It's similar to this:

>>> class N(object):
...   def __init__(self, value):
...     self.value = value
>>> n = N(3)
>>> value = n.value
>>> print value, n.value
3 3
>>> value = 4
>>> print value, n.value
4 3

Excepting crude hacks, if you really want to be able to modify the module's variable, you will need to import the module itself and modify the variable on the module. But generally, having to do this is indicative of bad design. If you are the writer of the foo module in question, you may want to look at some other, more Pythonic ways to solve your problem.

LeafStorm
A: 

from foo import * is frowned upon (by me, by Google's style guide, by the OLPC style guide - which you should see, as it has the best explanations of why this is bad - but not by PEP-8, unfortunately). - it makes for unreadable code.

Consider:

from foo import *
from bar import *
from baz import *

dostuff()

If you have an error running dostuff(), where do you look for the problem? It could have come from any of those imports.

For readable, maintainable code, stick with from foo import bar. For readable, modular, maintainable code, don't hack with globals - extend bar (by subclassing, if you can't change the upstream source) to expose methods for modifying the values you need to access.

James Polley
A: 

Short answer: No, it's impossible, and you'll have to use a prefix.

It's important to understand that from foo import x, y is copying x to your namespace. It's equivallent to:

import foo
# COPY TO YOUR NAMESPACE
x = foo.x
y = foo.y
# `from foo import` does NOT leave `foo` in your namespace
def foo

This way, each module will get a local copy of x and y. Changing x won't be seen in other modules, and you won't see changes other modules do :-(

To change the central copy of a variable you must import the module itself: import foo and change foo.x. This way only one copy exists and everybody is accessing it :-)

[The linked questions also mention the possibility to put the shared variable in the module builtin. DON'T! This would eliminate the prefix for reading it, but not for writing, and is extremely bad style.]

A note in defense of Python

If you resent the need to use a foo. prefix here, you'll probably also resent the need for the self. prefix to access object variables. The bottom line is that's how Python works - since you don't declare variables, there is no choice but to use prefixes.

But there is also an upside: when reading Python code, you easily see where each variable lives. IMHO that's very good.

Supporting evidence: in other languages like C++/Java, many people observe conventions like an m_ prefix on all object variable names to achieve a similar effect...

Style remarks

  1. You don't need import foo as bar, just use import foo.
    The as form doesn't do anything new, it just renames it, which is just confusing.
    It's only useful if "foo" is a very long name; a particularly accepted case is when "foo" lives deep in some package, so you can do import long.package.foo as foo.

  2. The from foo import * is considered very bad style in programs because:

    • The person reading your code won't know where names came from.

    • It pollutes your namespace, which can lead to subtle bugs when names from different modules clash.

    The explicit form from foo import x, y is OK, but starts suffering from the same problems if you use many names from the module.
    In such cases, it's best to import foo and explicitly write foo.x, foo.y.

Bottom line: when in doubt, a simple import foo is best.

Exception: It is very handy to use import * when experimenting at the interactive interpreter. Note however that it doesn't play well with reload(), so don't use it when debugging changing code. (To debug a module you are writing, it's best to launch a fresh interpreter inside the module's namespace - python -i mymodule.py / F5 in IDLE.)

Beni Cherniavsky-Paskin