EDIT: Alright, I pretty much figured it out (although it's not quite 100% what I wanted, it still works). It's the execfile()
function, I can't believe I didn't know that was there.
I wasn't really sure how to phrase this question (and that's the reason my Google searches have turned up virtually nothing on this)... but here goes. I'm going to give a simplified version of what I'm trying to do. So let's say I have two files, main.py
and extra.py
. The latter looks something like this:
# extra.py
def setfoo(): # sets "foo" to 5 even if it is unassigned
global foo
foo = 5
So pretty straightforward if I run this in the console:
>>> setfoo()
>>> foo
5
Now let's head back over to main.py
. I'll set up an import statement that imports everything from extra.py
:
# main.py
from extra import *
setfoo()
print foo
Everything works fine up until the last line; however, when main.py
tries to access foo
, it doesn't recognize it since foo
is actually stored under the file extra.py
. If I import everything again after I run setfoo()
, foo
will be imported and everything will work fine. Like so:
# main.py
from extra import *
setfoo()
from extra import *
print foo
Alternatively, if I use a standard import
statement instead of a from...import
statement, there is no need to reimport everything, since the data from extra.py
is being directly accessed rather than copied over. So this will work also:
# main.py
import extra
extra.setfoo()
print extra.foo
However, I really don't want to have to type out extra.setfoo()
every time I want to run setfoo()
, nor do I want to reimport extra.py
each time I use said function. I would like to know if there is a workaround to this. Ideally, there would be a way to modify extra.py
so that the code I set up in the original version of main.py
works properly. (EDIT: It seems multiple people have misinterpreted this–I am willing to modify extra.py
, it's main.py
that I don't want to change, aside from the import statement at the top, to get this code to work.) If this isn't possible I would also consider using a different method of importing extra.py
(I'm thinking something similar to PHP's include
and require
statements, in which the imported code is literally just copied and pasted into the file), but I would highly prefer that this modified import statement still be only one line of code, and not very lengthy. So in other words, using file handling plus an exec
statement probably wouldn't be very convenient for this purpose.
Speaking of exec statements, I really don't care much at all how bad the coding practices I use are. I really just need a way to get this to work since the real version of this extra.py
file is something I plan on using in almost all of my projects from now on, and I don't want to take up a lot of extra space in my code each time I import this file. Any help would be appreciated.
EDIT: It seems that a lot of people reading this aren't exactly clear on what I'm trying to accomplish, so here is the real version of my code. It's a syntax hack I put together to achieve "inline variable assignment". Here is the code (which works fine if you don't attempt to import it into another file):
class use_obj(object):
def __rshift__(self, other): return other
def use(**kwargs):
for var in kwargs: exec 'global ' + var + '; ' + var + ' = kwargs[var]'
return use_obj()
The syntax looks like this:
print use(x = 5, y = 8) >> str(x) + " times " + str(y) + " equals " + str(x*y)
The code itself is pretty gross, but I've always wanted a way to perform inline variable assignment since I'm a big fan of inline if statements, list comprehensions, lambdas + reduce()
, etc. The reason I can't simply have the function return the assigned variables is because use(x = 5, y = 8)
is an expression (not a statement) that returns a weird object that I then shove into the code using the >>
operator, and the weird object that the use()
function returned magically disappears due to the way I set up the __rshift__()
function.
I think the code would lose a lot of its beauty and novelty if it were to look like this:
print use(x = 5, y = 8) >> str(extras.x) + " times " + str(extras.y) + " equals " + str(extras.x*extras.y)