Python variable declared in 'for' loop not seen outside of loop - python

I know there are quite a few "python scope questions" here but I am VERY rusty with python and I am really confused about a "UnboundLocalError" problem I keep getting. I have read that 'for' loops do not have a contained scope yet my code seems to be acting in that way... My code looks like this:
`
...
for b in blocks[:]:
if b.contains(CONSTANT_NUM):
r = b.split(CONSTANT_NUM+2)
if r: blocks.append(r)
Foo= struct.unpack('<H', b.data)[0]
Bar = Foo
...
print("Foo: 0x%x" % (Foo))
`
Whenever I run this, I get the error "UnboundLocalError: local variable 'Foo' referenced before assignment". When I instead try and print Bar I get the same error. Why is the assignment not being carried outside of the 'for' loop?

It could be very likely that your loop never went into the if statement and hence Foo was never initialized.
You need to initialize it before the loop just to make sure that if that conditional is never met, you have something to print.

In your case, if the 1st if condition is failing, then the compiler won't reach the Foo = ... statement. Which will result in the error you are getting now.

The error indicates that at the time of checking the variable foo you have not yet initialized.
you should initialize it before the loop.

Related

Preferable way to get rid of 'redefined-outer-name' from pylint

For the following Python code
def add_func(a,b):
print(a+b)
a = 2
b = 3
add_func(a,b)
pylint will state
W0621: Redefining name 'a' from outer scope (line 4) (redefined-outer-name)
...
I can rename it as (perhaps due to a and b outside function will interfere add_func)
a_input = 2
b_input = 3
add_func(a_input,b_input)
to get rid of the message from pylint. But, _input looks somehow lengthy. Is there any recommended coding practice to get rid of the outer scope message from pylint?
the main usecase of a function is to pass arguments directly into it, so in this case the simplest way to input those would be:
add_func(2,3)
If you want to pass in varibales, name them after their usecase for readability purposes (It is generally not recommended to have a single char as variable name, with a few exceptions like i for loops)

Python list variable scope issues

I have the following code:
def myFunction(param, param):
myList = ["",[],[],[]]
#code to fill up myList
for q,d in enumerate(detailCollection):
#all the fun stuff here
yield{
"var1":myList[0],
"var2":myList[1],
#and so on
}
The error I am getting is as follows:
NameError: name 'myList' is not defined
Coming from the lines in the yield statement
For privacy purposes I haven't included actual code, but this is identical situation of what is happening. Why is it saying that myList is not defined when it is clearly in the same function scope, and how can I fix this problem? I would rather not move the myList variable all the way out and call it a global variable, to keep the code clean and concise is there a way to do this without moving myList declaration/definition?
So I didn't realize I had an extra _ laying around in my yield statement. No biggy :) Problem solved.

Scoping with Nested Functions in Python

This question is similar to others asked on here, but after reading the answers I'm not grasping it and would appreciate further guidance.
While sketching new code I find myself adding a lot of statements like:
print('var=')
pprint(var)
It became tedious always writing that, so I thought I could make it into a function. Since I want to print the variable name on the preceding line, I tried:
def dbp(var):
eval('print(\'{0}=\')'.format(var))
eval('pprint({0})'.format(var))
so then I do do things like:
foo = 'bar'
dbp('foo')
which prints
foo=
'bar'
This is all great, but when I go to use it in a function things get messed up. For example, doing
def f():
a = ['123']
dbp('a')
f()
raises a NameError (NameError: name 'a' is not defined).
My expectation was that dbp() would have read access to anything in f()'s scope, but clearly it doesn't. Can someone explain why?
Also, better ways of printing a variable's name followed by its formatted contents are also appreciated.
You really should look at other ways to doing this.
The logging module is a really good habit to get into, and you can turn off and on debug output.
Python 3.6 has f'' strings so you would simplify this to:
pprint(f'var=\n{var}`)`
However, here's an example (not recommended) using locals():
In []:
def dbp(var, l):
print('{}='.format(var))
pprint(l[var])
def f():
a = 1
dbp('a', locals())
f()
Out[]:
a=
1
first of all, id like to say that eval is a high security risk for whoever is going to be running that code.
However, if you absolutely must, you can do this.
def dbp(var):
env = {'var': var}
# Adding global variables to the enviroment
env.update(globals())
eval("print('{0}=')".format(var))
eval('pprint(var)', env)
def f():
a = ['123']
dbp('a')
you can then do
>>> f()
a=
'a'

Pandas Nested functions: apply does not seem to recognize internal function

I have a nested function such that
def f(l):
def g(index):
print index
l.apply(lambda x :x if x else g(x.name))
g(index) is an internal function of f(x). l is a 'pandas.core.series.Series' object which contains sets
>>> linked_on
1 set([xyz.com])
3 set([])
Name: EMAIL_ID, dtype: object
It seems like the internal function is not being recognized by the program and it just flows through in the else case without affecting anything. What I want is for the apply to call the internal function on the value if the set is empty. I put a breakpoint in the function but it never goes into it. When I try to break outside and run the function in the interpreter I get
NameError: global name 'g' is not defined
But I never get this error while running the code as is and it just flows through without giving any errors but also not going into the internal function. Any help into explaining this phenomenon will be greatly appreciated

Python Error: local variable 'last_card' referenced before assignment

The program keeps on telling me that 'last_card' is referenced before the assignment and it is. However, how can I by pass this error. If you look at the code, last_card is referenced in the first if statement. I want to use its value from the first "IF" statement and use it in the second. How can I do that?
if region == "showCardHistory":
temp = re.search(r'Card History for Slot (A|B|\d+)(.*)',line)
if temp:
last_card = temp.group(1)
temp = re.search(r'Secs since boot\s+:\s+(\d+)',line)
if temp:
card_slot_string = re.match(r'(A|B)',line)," CPM ",last_card,":"," IOM ",last_card
Python doesn't know for sure that the 1st if clause will be called. So, in order to be safe, it will assume at compile-time that last_card hasn't yet been declared. When you reference it in your 2nd if clause, the case may happen that the 1st if clause didn't evaluate True, and then it will have an UnassignedError.

Categories

Resources