Accessing variable inside a function from external file? - python

I have a file
outSimulation.py this file has a function called
outlet1 and inside this function there is a variable called data
I want to access this data variable from another program called main.py
I have tried it with absolute imports
from outSimulation import outlet1
values = outlet1.data()
but it doesnt work. Any help is appreciated.

You cannot* access a variable which is local to a function from outside the function.
If you want to access the value of data from a function which is called by outlet1(), you should pass data to that function.
If you want to access the value of data after outlet1() finishes running, you should return data (possibly along with other things) from outlet1().
Alternatively, you can make data a module-level variable. Assuming you assign something to data within outlet1(), you would make it a module-level variable using the global keyword,
def outlet1():
global data
# code
data = ...
# more code
but this tends to be less clean than the other methods.
There are other solutions if outlet1() is defined within a class, but your question suggests that's not the case so I won't get into that.
*Well... uh, never mind. There are some wacky things you can do for debugging, but you're better off not considering those for your purposes.

Functions are not classes, and are specifically designed so that you CAN'T do what you're trying to do. That's the whole basis of functional programming and the concepts behind encapsulation. Even if your function was a class, your code still wouldn't work because you're trying to call the variable as a function (by adding () to data).
Either create data as a global variable that can be referenced inside the function or have the function return a tuple with multiple items, including the original return value and the data variable (messy). You could also rewrite the function in an object-oriented way if that approach suits your problem domain, in which case your code above would make more sense.

Related

Using variables from a function in another python program

So I'm trying to write a python program to integrate into a greater in-house developed python application. This program I'm writing needs to generate an xml document and populate the fields with data stored in variables from another function in a different module.
After realizing I can't have both programs import each other (main program needs to call xmlgen.py to generate the xml doc, while xmlgen.py needs to utilize variables in the main program to generate that doc), I'm a little bit at a loss as to what to do here.
In the example shown below, xmlgen.py needs to use variables from the function sendFax in Faxer.py. Faxer.py needs to call xmlgen.py to generate the document.
snippet from xmlgen.py:
from lxml import etree
from Faxer import coverPage, ourOrg, ourPhonenum, ourFaxnum, emailAddr, sendReceipt, webAddr, comments
from Faxer import sendFax
def generateXml():
#xml file structure
root = etree.Element('schedule_fax')
...
~ A bunch of irrelevant xml stuff
...
grandchild_recipient_name = etree.Element('name')
grandchild_recipient_name.text = cliName
child_recipient.append(grandchild_recipient_name)
Now the piece of the main program I need to utilize the "cliName" variable from...
def sendFax(destOrg, destFax, cliName, casenum, attachments, errEAddr, comment, destName):
creds=requests.auth.HTTPBasicAuth(user,password)
allData=''
allData+='<schedule_fax>\n'
allData+='<cover_page>\n'
allData+='<url>'+prepXMLString(coverPage)+'</url>\n'
allData+='<enabled>true</enabled>\n'
allData+='<subject>'+prepXMLString(cliName)+' - case # '+str(casenum)+'</subject>\n'
Now when I try to import sendFax function from Faxer.py, I'm unable to call any of the variables from the function like,
grandchild_recipient_name.text = sendFax.cliName
does not work. What am i doing wrong here?? I'm not a python guru and am in fact quite new to all of this, so I'm hoping it's something simple. Should I just dump everything into a new function in the main program?
As pointed out above, you are trying to reference cliName as if it is an attribute of the function. This would be closer to being correct if sendFax was a class, but that's another subject. The snippet you have provided is simply a function definition. It doesn't guarantee that this function is ever actually used or give you any idea what cliName actually is, cliName is just the name used by the function internallt to describe the 3rd value supplied as input.
What you need to do is find where sendFax is actually used, rather than where it is defined. Then look at what the variables are called which are passed into it. There are two ways to pass variables into a function: by position and by name. If the variables are being passed by pposition you will find something like:
sendFax(some_name,some_other_name,yet_another_name,...
The third one of these will be the variable which becomes cliName inside the function.
If being passed by name you will see something like
sendFax(cliName=yet_another_name,...
Where once again yet_another_name is the thing which becomes cliName.
Depending on how the programme is structured you may be able to refer to yet_another_name from your program and get the value you need.
from Faxer import yet_another_name
But this will only work if Faxer runs and finishes with the one and only value of yet_another_name assigned. If Faxer iterates through lots of values of yet_another_name, or simply doesn't run sensibly when called as an import you'll need a more sophisticated approach.

Running function code only when NOT assigning output to variable?

I am looking for a way in python to stop certain parts of the code inside a function but only when the output of the function is assigned to a variable. If the the function is run without any assignment then it should run all the inside of it.
Something like this:
def function():
print('a')
return ('a')
function()
A=function()
The first time that I call function() it should display a on the screen, while the second time nothing should print and only store value returned into A.
I have not tried anything since I am kind of new to Python, but I was imagining it would be something like the if __name__=='__main__': way of checking if a script is being used as a module or run directly.
I don't think such a behavior could be achieved in python, because within the scope of the function call, there is no indication what your will do with the returned value.
You will have to give an argument to the function that tells it to skip/stop with a default value to ease the call.
def call_and_skip(skip_instructions=False):
if not skip_instructions:
call_stuff_or_not()
call_everytime()
call_and_skip()
# will not skip inside instruction
a_variable = call_and_skip(skip_instructions=True)
# will skip inside instructions
As already mentionned in comments, what you're asking for is not technically possible - a function has (and cannot have) any knowledge of what the calling code will do with the return value.
For a simple case like your example snippet, the obvious solution is to just remove the print call from within the function and leave it out to the caller, ie:
def fun():
return 'a'
print(fun())
Now I assume your real code is a bit more complex than this so such a simple solution would not work. If that's the case, the solution is to split the original function into many distinct one and let the caller choose which part it wants to call. If you have a complex state (local variables) that need to be shared between the different parts, you can wrap the whole thing into a class, turning the sub functions into methods and storing those variables as instance attributes.

python: is there anyway to initialize a variable only one time?

I want to do matching my time-series data to meta data from a given file.
In my code, main function calls "create_match()" function every 1 minute. Inside "create_match(), there is a "list_from_file()" function to read data from file and store in lists to perform matching.
The problem is that my code is not effective since every 1 minute, it reads the file and rewrite in the same lists. I want to read file only one time (to initialize lists only one time), and after that ignoring the "list_from_file()" function. I do not want to just move this task to main function and pass lists through function.
Does python have a special variable like static variable in c programming?
Python does not have a static variable declaration; however, there are several fairly standard programming patterns in python to do something similar. The easiest way is to just use a global variable.
Global Variables
Define a global variable and check it before running your initialize function. If the global variable has already been set (ie. the lists you're reading in), just return them.
CACHE = None
def function():
global CACHE
if CACHE is None:
CACHE = initialize_function()
return CACHE
You can use a class:
class Match (object):
def __init__(self):
self.data = list_from_file()
def create_match(self):
# do something with `self.data` here
Make an instance:
match = Match()
This calls list_from_file().
Now, you can call create_match() repeatedly with access to self.data
import time
for x in range(10):
match.create_match()
time.sleep(60)
There are lots of ways.
You can make a variable part of a class - not a member of the object, but of the class itself. It is initialized when the class is defined.
Similarly you can put a variable at the outer level of a module. It will belong to the module, and will be initialed when the module is imported the first time.
Finally there's the hack of defining an object as a default parameter to a function. The variable will be initialized when the function is defined, and will belong to the function. You will only be able to access it with the parameter name, and it can be overridden by the caller.

Update locals from inside a function

I would like to write a function which receives a local namespace dictionary and update it. Something like this:
def UpdateLocals(local_dict):
d = {'a':10, 'b':20, 'c':30}
local_dict.update(d)
When I call this function from the interactive python shell it works all right, like this:
a = 1
UpdateLocals(locals())
# prints 20
print a
However, when I call UpdateLocals from inside a function, it doesn't do what I expect:
def TestUpdateLocals():
a = 1
UpdateLocals(locals())
print a
# prints 1
TestUpdateLocals()
How can I make the second case work like the first?
UPDATE:
Aswin's explanation makes sense and is very helpful to me. However I still want a mechanism to update the local variables. Before I figure out a less ugly approach, I'm going to do the following:
def LoadDictionary():
return {'a': 10, 'b': 20, 'c': 30}
def TestUpdateLocals():
a = 1
for name, value in LoadDictionary().iteritems():
exec('%s = value' % name)
Of course the construction of the string statements can be automated, and the details can be hidden from the user.
You have asked a very good question. In fact, the ability to update local variables is very important and crucial in saving and loading datasets for machine learning or in games. However, most developers of Python language have not come to a realization of its importance. They focus too much on conformity and optimization which is nevertheless important too.
Imagine you are developing a game or running a deep neural network (DNN), if all local variables are serializable, saving the entire game or DNN can be simply put into one line as print(locals()), and loading the entire game or DNN can be simply put into one line as locals().update(eval(sys.stdin.read())).
Currently, globals().update(...) takes immediate effect but locals().update(...) does not work because Python documentation says:
The default locals act as described for function locals() below:
modifications to the default locals dictionary should not be
attempted. Pass an explicit locals dictionary if you need to see
effects of the code on locals after function exec() returns.
Why they design Python in such way is because of optimization and conforming the exec statement into a function:
To modify the locals of a function on the fly is not possible without
several consequences: normally, function locals are not stored in a
dictionary, but an array, whose indices are determined at compile time
from the known locales. This collides at least with new locals added
by exec. The old exec statement circumvented this, because the
compiler knew that if an exec without globals/locals args occurred in
a function, that namespace would be "unoptimized", i.e. not using the
locals array. Since exec() is now a normal function, the compiler does
not know what "exec" may be bound to, and therefore can not treat is
specially.
Since global().update(...) works, the following piece of code will work in root namespace (i.e., outside any function) because locals() is the same as globals() in root namespace:
locals().update({'a':3, 'b':4})
print(a, b)
But this will not work inside a function.
However, as hacker-level Python programmers, we can use sys._getframe(1).f_locals instead of locals(). From what I have tested so far, on Python 3, the following piece of code always works:
def f1():
sys._getframe(1).f_locals.update({'a':3, 'b':4})
print(a, b)
f1()
However, sys._getframe(1).f_locals does not work in root namespace.
The locals are not updated here because, in the first case, the variable declared has a global scope. But when declared inside a function, the variable loses scope outside it.
Thus, the original value of the locals() is not changed in the UpdateLocals function.
PS: This might not be related to your question, but using camel case is not a good practice in Python. Try using the other method.
update_locals() instead of UpdateLocals()
Edit To answer the question in your comment:
There is something called a System Stack. The main job of this system stack during the execution of a code is to manage local variables, make sure the control returns to the correct statement after the completion of execution of the called function etc.,
So, everytime a function call is made, a new entry is created in that stack,
which contains the line number (or instruction number) to which the control has to return after the return statement, and a set of fresh local variables.
The local variables when the control is inside the function, will be taken from the stack entry. Thus, the set of locals in both the functions are not the same. The entry in the stack is popped when the control exits from the function. Thus, the changes you made inside the function are erased, unless and until those variables have a global scope.

add a local variables to a function

is it possible to add a local varible to a function, just before calling it ? if yes how ?
EDIT:REASON
i noticed that all my views in django are using
render_to_response(template_name,locals())
now i created a middleware and i wanted to add one more local variable using the
def process_view():
method of it .so that i don't have to modify the views .
The local scope for a function does not exist until the function is called, so it's not possible to do this. You could do this for a closure, but the next person to have to maintain the code would hunt you down and kill you.
Although I also think it is pretty useless, I thought that you may enclose the function in either a 'with' statement or another function, like the code below. Of course, this approach can be accomplished directly within the function of interest. In fact, you are adding the local variable 'during' the function declaration. See if this fits your needs!
#!/usr/bin/python
def my_funct(_local):
"""My function of interest
"""
print "Local argument was %s" % str(_local)
return "Finished"
def localize(fct, local_var):
"""
"""
return fct(_local = local_var)
## Use function to 'localize' variable
localize(my_funct, local_var="LOCAL_VARIABLE")
## Same effect without supplementary function :
my_funct(_local="LOCAL_VARIABLE")
try:
print local_var
except:
print "No such global variable"
Just some thoughts :)
Cheers
So if you’re one of those lazy
programmers and you like keeping code
particularly concise, you can take
advantage of a built-in Python
function called locals(). It returns a
dictionary mapping all local variable
names to their values, where “local”
means all variables that have been
defined within the current scope.
source
It is a trick in order to not have to explicitly list all of the variables you need to pass in to the function. In this case, you need to explicitly state a variable to pass in. Therefore, you should not be using locals() in the calls you are making in your middle-ware, as the trick was not designed to be used like that.
i mangaged to do that using decorators.

Categories