问题
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?
回答1:
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.
回答2:
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
You don't need
import foo as bar
, just useimport foo
.
Theas
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 doimport long.package.foo as foo
.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 toimport foo
and explicitly writefoo.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.)
回答3:
By using import foo from bar
you don't import bar
as a variable but as a constant.
回答4:
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.
来源:https://stackoverflow.com/questions/2019877/cross-module-variable