Skip to content Skip to sidebar Skip to footer

Conflicting Variable And Function Names In Python

Let's say I've got the following functions: def xplusy(x, y): return x+y def xplus1(x): xplusy = xplusy(x, 1) return xplusy Now if I call a = xplus1(4) it throws the

Solution 1:

In Python, functions are data, and typing is dynamic. This means that the following lines are valid Python:

def func(x):
    return x + 3func = 3

func is now an int. The original function func is no longer referenced. The fact that func was originally a function doesn't have any bearing on what types of data can be assigned to it in the future. (This is what "dynamic typing" means.)

Therefore, since there's no static typing, and "function" is a valid data type, it wouldn't make sense for the Python interpreter to distinguish between a function and a piece of data referenced by the same name. Therefore, within a given scope, there's no way to use the same unqualified variable name to mean two different things.

In your particular case, if the code in your xplus1 function meant anything, it would mean "compute the value of xplusy(x,1) and assign that value to the variable xplusy -- thereby losing the reference to the functionxplusy." However, within the scope of a function, the interpreter won't let you make an assignment to a variable outside of that scope, so it assumes that by writing an assignment statement, you're introducing a new local variable xplusy. The local variable, however, hasn't been defined yet, so your attempt to call it, xplusy(x,1), fails. The globally defined function is not called as a fall-back because, again, you can't have two unqualified names be identical and point to different data in the same scope.


Another example demonstrating the "no duplication of variable names within one scope" rule (which I actually only just discovered while playing around with the prompt in my attempt to construct this answer):

>>>deff1():...    a = xplusy(3,4)...    xplusy = 5...print xplusy...>>>f1()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in f1
UnboundLocalError: local variable 'xplusy' referenced before assignment
>>>deff1():...    a = xplusy(3,4)...print a...>>>f1()
7

This demonstrates that it really is the scope, not the statement that requires unique names.


EDIT: This is a really cool post that explains this and other scoping-related behavior: http://me.veekun.com/blog/2011/04/24/gotcha-python-scoping-closures/

Solution 2:

In python function is first class object which mean it is as any other object.

More information about What are “first class” objects?

Solution 3:

The reason this occurs is because xplusy exists in your scope as a global variable which cannot be changed unless you explicitly say xplusy is global.

defxplusy(x,y):
    return x+y

defxplus1(x):
    global xplusy
    xplusy = xplusy(x,1)
    return xplusy

however, this will make xplusy refer to an int, float or whatever xplusy returned the first time, meaning that after the first time it will throw TypeErrors.

The more pythonic way to do this would most likely be

defxplus1(x):
    return xplusy(x,1)

or using the functools module:

from functools import partial
xplus1 = partial(xplusy,y=1) #since you wanted to override y with1

if you don't care about which argument is overridden, you could simply do

xplus1 = partial(xplusy,1)

Solution 4:

In Python, xplusy can reference anything. You can do this:

defxplusy(x, y):
    return x+y

defotherfunction(x, y):
    return x*y

defxplus1(x):
    xplusy = otherfunction
    return  xplusy(x, 1)

And xplusy variable will reference to otherfunction in xplus1 scope.

xplus1(2)
>>>2

Result is 2 * 1 instead 2 + 1. Be careful with assignments.Use as many variables as you need.

Post a Comment for "Conflicting Variable And Function Names In Python"