For example I have code like this:
def test():
v = tf.get_variable('test') # => foo/test
with tf.variable_scope('foo'):
test()
Now I want to make a variable outside of scope 'foo':
def test():
with tf.variable_scope('bar'):
v = tf.get_variable('test') # foo/bar/test
But it is placed as 'foo/bar/test'. What should I do in test() body to place it as 'bar/test' without 'foo' root?
You can clear the current variable scope by providing an instance of an existing scope. So in order to pull this off, just make a reference to the top-level variable scope and use it:
top_scope = tf.get_variable_scope() # top-level scope
def test():
v = tf.get_variable('test', [1], dtype=tf.float32)
print(v.name)
with tf.variable_scope(top_scope): # resets the current scope!
# Can nest the scopes further, if needed
w = tf.get_variable('test', [1], dtype=tf.float32)
print(w.name)
with tf.variable_scope('foo'):
test()
Output:
foo/test:0
test:0
tf.get_variable() ignores the name_scopebut not variable_scope. If you want to obtain 'bar/test', you can try the following:
def test():
with tf.variable_scope('bar'):
v = tf.get_variable('test', [1], dtype=tf.float32)
print(v.name)
with tf.name_scope('foo'):
test()
Refer to this answer for a complete explanation: https://stackoverflow.com/a/37534656/8107620
A workaround would be to set the scope name directly:
def test():
tf.get_variable_scope()._name = ''
with tf.variable_scope('bar'):
v = tf.get_variable('test', [1])
Related
So what I'm trying to do is I need to assign a variable to use in several functions. But that variable should not be a global variable. How can I do that if it is possible?
Edit: I did forgot one thing. This is for my project and most of it is finished but this. My code needs to be non-repeated as much as it can. I have 5 variables and 15 functions to use some or all of that variables.
Edit2: Let me just post a function here.
def draw_stairs(top_stair_wide, stair_height, stair_count, character):
for o in range(stair_count):
for b in range(stair_height):
draw_straight_line(top_stair_wide, character)
print("")
top_stair_wide += 3
What I need to do is when I use that function, I need to fill "top_stair_wide", "stair_height", "stair_count" with a variable that is not global. I can't just put numbers because I will use those variables in 14 different functions again with maths.
I have a function that draws straight line and before, it inputs and returns character so those are not the problem.
Create a class, make the variables instance variables and turn the functions into methods. Then you can access the instance variables in each method without the explicit need to pass them around.
class C:
def __init__(self, var1, var2, var3):
self.var1 = var1
self.var2 = var2
self.var3 = var3
def add_them(self):
return self.var1 + self.var2 + self.var3
def multiply_them(self):
return self.var1 * self.var2 * self.var3
And so on.
You need parameter(s) in your function definition and then pass your variable(s) as argument(s) when you call it.
Using a main function as you told me in a comment, you could write it like this:
def main():
# Here are your NOT GLOBAL variables:
top_stair_wide = 1
stair_height = 2
stair_count = 3
character = "O"
def draw_stairs(top_stair_wide, stair_height, stair_count, character):
for o in range(stair_count):
for b in range(stair_height):
draw_straight_line(top_stair_wide, character)
print("")
top_stair_wide += 3
# ... more definitions follow
# Then call the functions...
# Job done when you execute the program:
main()
Alternatively:
def main(top_stair_wide, stair_height, stair_count, character): # <-- cram all the expected arguments there
def draw_stairs(top_stair_wide, stair_height, stair_count, character):
for o in range(stair_count):
for b in range(stair_height):
draw_straight_line(top_stair_wide, character)
print("")
top_stair_wide += 3
# ... more definitions follow
# Then call the functions...
# Job done when you execute the program:
main(1, 2, 3, "O")
It's also possible using kwargs, because then you have to know the arguments when you call main() and not when you define it:
def main(**kwargs):
def draw_stairs(**kwargs):
for o in range(kwargs["stair_count"]):
for b in range(kwargs["stair_height"]):
draw_straight_line(kwargs["top_stair_wide"], kwargs["character"])
print("")
kwargs["top_stair_wide"] += 3
# ... more definitions follow
# Then call the functions...
function1(**kwargs)
function2(**kwargs)
function3(**kwargs)
# Job done when you execute the program:
main(top_stair_wide = 1,
stair_height = 2,
stair_count = 3,
character = "O")
You can pass it to your functions like:
def func1(variable):
# your logic here with variable
return 'something'
def func2(variable):
# your logic here with variable
return 'something'
Or you can set it as constant in current file as:
VARIABLE = 'variable'
def func1():
# your logic here with VARIABLE
return 'something'
def func2():
# your logic here with VARIABLE
return 'something'
Another option is using a dictionary storing the shared parameters and only passing this dictionary (rather than all variables separately) as an argument:
def add_params(params):
return params['var1'] + params['var2'] + params['var3']
def multiply_params(params):
return params['var1'] * params['var2'] * params['var3']
>>> params = {'var1': 1, 'var2', 2, 'var3': 3}
>>> add_params(params)
6
>>> multiply_params(params)
6
I have tried to search this but I don't quite understand. I am coming across this error so I formed a quick easy example.
def test():
global a
a = 0
a+=1
def test2():
a+=1
print (a)
inp = input('a?')
if inp == 'a':
test()
test2()
When I input a. I expected the code to output 2. However, I get this error UnboundLocalError: local variable 'a' referenced before assignment. When I searched around about this, I found that you need to use global, but I already am using it.
So I don't understand. Can someone briefly explain what I'm doing wrong?
Thanks.
A global declaration only applies within that function. So the declaration in test() means that uses of the variable a in that function will refer to the global variable. It doesn't have any effect on other functions, so if test2 also wants to access the global variable, you need the same declaration there as well.
def test2():
global a
a += 1
print(a)
1) You can return the modified value like:
def test():
a = 0
a+=1
return a
def test2(a):
a+=1
print (a)
inp = input('a?')
if inp == 'a':
a = test()
test2(a)
2) Or you can use a class:
class TestClass:
a = 0
def test(self):
self.a = 0
self.a+=1
def test2(self):
self.a+=1
print (self.a)
Usage of option 2:
>>> example = TestClass()
>>> example.test()
>>> example.test2()
2
I am learning python and have one question about how to save a dictionary value via a python function.
import copy
def func():
b = {'1':'d'}
a = copy.deepcopy(b)
global a
a = {}
func()
print a
The printout is still {}, how to make it be {'1':'d'}?
You need to say that you are accessing the global variable a, inside the function, like this
def func():
global a
b = {'1': 'd'}
a = copy.deepcopy(b)
But, prefer not doing something like that. Instead, return the copy and then store it in the calling place, like this
import copy
a = {}
def func():
b = {'1': 'd'}
return copy.deepcopy(b)
a = func()
print a
i moved the global a into the function definition.
#! /usr/bin/python
import copy
def func():
global a
b = {'1':'d'}
a = copy.deepcopy(b)
a = {}
func()
print a
You are defining 'a' in two different scopes, one in the "global" scope, one in the function scope. You will need to return copy.deepcopy(b) and set that to the value of the outer defined 'a'.
import copy
def func():
b = {'1':'d'}
return copy.deepcopy(b)
global a
a = func()
print a
Say I have some code that creates several variables:
# Some code
# Beginning of the block to memoize
a = foo()
b = bar()
...
c =
# End of the block to memoize
# ... some more code
I would like to memoize the entire block above without having to be explicit about every variable created/changed in the block or pickle them manually. How can I do this in Python?
Ideally I would like to be able to wrap it with something (if/else or with statement) and have a flag that forces a refresh if I want.
Conceptually speaking, it woul dbe like:
# Some code
# Flag that I can set from outside to save or force a reset of the chache
refresh_cache = True
if refresh_cache == False
load_cache_of_block()
else:
# Beginning of the block to memoize
a = foo()
b = bar()
...
c = stuff()
# End of the block to memoize
save_cache_of_block()
# ... some more code
Is there any way to do this without having to explicitly pickle each variable defined or changed in the code? (i.e. at the end of the first run we save, and we later just reuse the values)
How about using locals() to get a list of the local variables, storing them in a dict in pickle, then using (below is more conceptual):
for k,v in vars_from_pickle:
run_string = '%s=%s' % (k,v)
exec(run_string)
to restore your local stack. Maybe its better to use a list instead of a dict to preserve stack ordering.
There are a lot of ways to go about this but I think the way that's closest to what you're describing would be to use pythons module scope as your memoized and import or reload as needed. Something like this:
# a.py
import b
print b.a, b.b
b.func(5)
b.b = 'world'
print b.a, b.b
if b.needs_refresh():
reload(b)
print b.a, b.b
With your "variable scope" being the module b:
# b.py
a = 0
b = 'hello'
def func(i):
global a
a += i
def needs_refresh():
return a >= 5
Executing this results in what you'd expect:
0 hello
5 world
0 hello
Edit: to be allow you to copy and save the entire scope you could just use a class scope:
memo_stack = list()
class MemoScope(object):
def __init__(self):
self.a = 0
self.b = 'hello'
memo = MemoScope()
memo.a = 2
memo.b = 3
memo_stack.append(memo)
memo_stack.append(MemoScope())
for i, o in enumerate(memo_stack):
print "memo t%i.a = %s" % (i, o.a)
print "memo t%i.b = %s" % (i, o.b)
if o.a == 2:
memo_stack[i] = MemoScope()
print "refreshed"
# memo t0.a = 2
# memo t0.b = 3
# refreshed
# memo t1.a = 0
# memo t1.b = hello
I am trying to store a value in a module level variable for later retrieval.
This function when called with a GET method throws this error: local variable 'ICS_CACHE' referenced before assignment
What am I doing wrong here?
ICS_CACHE = None
def ical_feed(request):
if request.method == "POST":
response = HttpResponse(request.POST['file_contents'], content_type='text/calendar')
response['Content-Disposition'] = 'attachment; filename=%s' % request.POST['file_name']
ICS_CACHE = response
return response
elif request.method == "GET":
return ICS_CACHE
raise Http404
I constructed a basic example to see if a function can read module constants and it works just fine:
x = 5
def f():
print x
f()
---> "5"
Add
global ISC_CACHE
as the first line of your function. You are assigning to it inside the function body, so python assumes that it is a local variable. As a local variable, though, you can't return it without assigning to it first.
The global statement lets the parser know that the variable comes from outside of the function scope, so that you can return its value.
In response to your second posted example, what you have shows how the parser deals with global variables when you don't try to assign to them.
This might make it more clear:
x = 5 # global scope
def f():
print x # This must be global, since it is never assigned in this function
>>> f()
5
def g():
x = 6 # This is a local variable, since we're assigning to it here
print x
>>> g()
6
def h():
print x # Python will parse this as a local variable, since it is assigned to below
x = 7
>>> h()
UnboundLocalError: local variable 'x' referenced before assignment
def i():
global x # Now we're making this a global variable, explicitly
print x
x = 8 # This is the global x, too
>>> x # Print the global x
5
>>> i()
5
>>> x # What is the global x now?
8