Why is double considered a global name? - python

I've created the code below, when I import the module and attempt to run it I received the following error:
>>> import aiyoo
>>> aiyoo.bixidist(1,3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "aiyoo.py", line 50, in bixidist
currentDist = dist(X,Y,c)
File "aiyoo.py", line 39, in dist
distance = math.sqrt(math.pow((X-getLat(i)),2)+math.pow((Y-getLong(i)),2))
File "aiyoo.py", line 28, in getLat
xmlLat = double(xmlLat)
NameError: global name 'double' is not defined
The double function was used in order to convert the unicode output from the XML into a double as input for the functions to follow. So I do not understand why, it is considered to be a name when the aiyoo module is imported.
Here is the module, which was named aiyoo.py:
import math
import urllib2
from xml.dom.minidom import parseString
file = urllib2.urlopen('http://profil.bixi.ca/data/bikeStations.xml')
data = file.read()
file.close()
dom = parseString(data)
#this is how you get the data
def getID(i):
xmlID = dom.getElementsByTagName('id')[i].toxml()
xmlID = xmlID.replace('<id>','').replace('</id>','')
xmlID = int(xmlID)
return xmlID
def getLat(i):
xmlLat = dom.getElementsByTagName('lat')[i].toxml()
xmlLat = xmlLat.replace('<lat>','').replace('</lat>','')
xmlLat = double(xmlLat)
return xmlLat
def getLong(i):
xmlLong = dom.getElementsByTagName('long')[i].toxml()
xmlLong = xmlLong.replace('<long>','').replace('</long>','')
xmlLong = double(xmlLong)
return xmlLong
#this is how we find the distance for a given station
def dist(X,Y,i):
distance = math.sqrt(math.pow((X-getLat(i)),2)+math.pow((Y-getLong(i)),2))
return distance
#this is how we find the closest station
def bixidist(X,Y):
#counter for the lowest
lowDist = 100000
lowIndex = 0
c = 0
end = len(dom.getElementsByTagName('name'))
for c in range(0,end):
currentDist = dist(X,Y,c)
if currentDist < lowDist:
lowIndex = c
lowDist = currentDist
return getID(lowIndex)

As answered by others, double is not a built-in type in python. You have to use, float instead. Floating point is implemented using double in C [ ref ].
And as to the main part of your question i.e. "why the double considered a global name?", when you use a variable-name say double, which is not found in local context, the next lookup is in global context. It is then, if it is not found even in global context, the exception is raised, saying NameError: global name 'double' is not defined.
Happy Coding.

There is no double type in Python. And if you look at the error it complains that it can't find anything named double. The floating-point type in Python is named float.

it should be xmlLat = float(xmlLat)
Python float is same as double of other languages. ( 64 bit )
http://codepad.org/AayFYhEd

Like the other 2 answers so far have said, Python doesn't have a double variable type, instead it has float.
Now for the question in your title and possibly another source of confusion for you. The reason the interpreter is saying "NameError: global name 'double' is not defined" is because of how Python searches for names of functions, variables, objects, etc. This pattern is described by Python's namespace and scope rules. Because you tried to call the nonexistent function Double from within a function without qualifying it (ie. SomeObject.Double(x)), Python first looks for an object of that name in the local namespace (namespace of the current function that is running), then the local namespace of the enclosing functions, then the global namespace, and finally the built-in namespace. The reason the interpreter gave you that message is because of the order of Python's search for the definition of Double(). global namespace was the last place it checked before looking for it in the built-ins (which are Python's coding, not yours, so I guess it wouldn't make sense for the interpreter to say "NameError: built-in name 'double' is not defined"). At least I think this is what's going on. I'm still not a very seasoned programmer, so I trust someone else will correct me if I got something wrong.

Related

Python Dictionary scores [duplicate]

Given the following integers and calculation
from __future__ import division
a = 23
b = 45
c = 16
round((a/b)*0.9*c)
This results in:
TypeError: 'int' object is not callable.
How can I round the output to an integer?
Somewhere else in your code you have something that looks like this:
round = 42
Then when you write
round((a/b)*0.9*c)
that is interpreted as meaning a function call on the object bound to round, which is an int. And that fails.
The problem is whatever code binds an int to the name round. Find that and remove it.
I got the same error (TypeError: 'int' object is not callable)
def xlim(i,k,s1,s2):
x=i/(2*k)
xl=x*(1-s2*x-s1*(1-x)) / (1-s2*x**2-2*s1*x(1-x))
return xl
... ... ... ...
>>> xlim(1,100,0,0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in xlim
TypeError: 'int' object is not callable
after reading this post I realized that I forgot a multiplication sign * so
def xlim(i,k,s1,s2):
x=i/(2*k)
xl=x*(1-s2*x-s1*(1-x)) / (1-s2*x**2-2*s1*x * (1-x))
return xl
xlim(1.0,100.0,0.0,0.0)
0.005
tanks
Stop stomping on round somewhere else by binding an int to it.
I was also facing this issue but in a little different scenario.
Scenario:
param = 1
def param():
.....
def func():
if param:
var = {passing a dict here}
param(var)
It looks simple and a stupid mistake here, but due to multiple lines of codes in the actual code, it took some time for me to figure out that the variable name I was using was same as my function name because of which I was getting this error.
Changed function name to something else and it worked.
So, basically, according to what I understood, this error means that you are trying to use an integer as a function or in more simple terms, the called function name is also used as an integer somewhere in the code.
So, just try to find out all occurrences of the called function name and look if that is being used as an integer somewhere.
I struggled to find this, so, sharing it here so that someone else may save their time, in case if they get into this issue.
In my case I changed:
return <variable>
with:
return str(<variable>)
try with the following and it must work:
str(round((a/b)*0.9*c))
Sometimes the problem would be forgetting an operator while calculation.
Example:
print(n-(-1+(math.sqrt(1-4(2*(-n))))/2)) rather
it has to be
print(n-(-1+(math.sqrt(1-4*(2*(-n))))/2))
HTH
There are two reasons for this error "TypeError: 'int' object is not callable"
Function Has an Integer Value
Consider
a = [5, 10, 15, 20]
max = 0
max = max(a)
print(max)
This will produce TypeError: 'int' object is not callable.
Just change the variable name "max" to var(say).
a = [5, 10, 15, 20]
var = 0
var = max(a)
print(var)
The above code will run perfectly without any error!!
Missing a Mathematical Operator
Consider
a = 5
b = a(a+1)
print(b)
This will also produce TypeError: 'int' object is not callable.
You might have forgotten to put the operator in between ( '*' in this case )
As mentioned you might have a variable named round (of type int) in your code and removing that should get rid of the error. For Jupyter notebooks however, simply clearing a cell or deleting it might not take the variable out of scope. In such a case, you can restart your notebook to start afresh after deleting the variable.
You can always use the below method to disambiguate the function.
__import__('__builtin__').round((a/b)*0.9*c)
__builtin__ is the module name for all the built in functions like round, min, max etc. Use the appropriate module name for functions from other modules.
I encountered this error because I was calling a function inside my model that used the #property decorator.
#property
def volume_range(self):
return self.max_oz - self.min_oz
When I tried to call this method in my serializer, I hit the error "TypeError: 'int' object is not callable".
def get_oz_range(self, obj):
return obj.volume_range()
In short, the issue was that the #property decorator turns a function into a getter. You can read more about property() in this SO response.
The solution for me was to access volume_range like a variable and not call it as a function:
def get_oz_range(self, obj):
return obj.volume_range # No more parenthesis

Get variable name from NameError object

if I catch a NameError exception using except:
try:
print(unknownVar)
except NameError as ne:
print(ne)
I get a string like :
NameError: name 'unknownVar' is not defined
I work in the context of eval'ed expressions and it whould be a useful information to me if I could obtain only the variable name (here "unknownVar" alone) and not the full string. I did not find an attribute for example in the NameError object to get it (perhaps does it exists, but I did not find it). Is there something better than parsing this string to do to get the information I need ?
Best Regards
Mikhaël
You can extract it using regex:
import re
try:
print(unknownVar)
except NameError as ne:
var_name = re.findall(r"'([^']*)'", str(ne))[0]
print(var_name) # output: unknownVar
Extract it from the string:
ne.args[0].split()[1].strip("'")
Unfortunately, error messages are not exactly Python's strong suit. However, there is actually an alternative to parsing the string, but it is quite "hacky" and only works with CPython (i.e. this will fail with PyPy, Jython, etc.).
The idea is to extract the name of whatever you wanted to load from the underlying code object.
import sys
import opcode
def extract_name():
tb = sys.exc_info()[2] # get the traceback
while tb.tb_next is not None:
tb = tb.tb_next
instr_pos = tb.tb_lasti # the index of the "current" instruction
frame = tb.tb_frame
code = frame.f_code # the code object
instruction = opcode.opname[code.co_code[instr_pos]]
arg = code.co_code[instr_pos + 1]
if instruction == 'LOAD_FAST':
return code.co_varnames[arg]
else:
return code.co_names[arg]
def test(s):
try:
exec(s)
except NameError:
name = extract_name()
print(name)
test("print(x + y)")
1. The Background of Code Object
Python compiles the original Python source code into bytecode and then executes that bytecode. The code is stored in "code objects", which are (partly) documented here. For our purpose, the following will suffice:
class CodeObject:
co_code: bytes # the bytecode instructions
co_varnames: tuple # names of local variables and parameters
co_names: tuple # all other names
If some code produces a NameError, it failed to load a specific name. That name must be either in the co_names or co_varnames tuple. All we have to figure out is which one.
While the code objects desribe the code statically, we also need a dynamic object that tells us the value of local variables and which instruction we are currently executing. This role is fulfilled by the "frame" (leaving out irrelevant details):
class Frame:
f_code: CodeObject # the code object (see above)
f_lasti: int # the instruction currently executed
You could think of the interpreter as basically doing the following:
def runCode(code):
frame = create_new_frame(code)
while True:
i = frame.f_lasti
opcode = frame.f_code.co_code[i]
arg = frame.f_code.co_code[i+1]
exec_opcode(opcode, arg)
frame.f_lasti += 2
The code to load a name then has a form like this:
LOAD_NAME 3 (the actual name is co_names[3])
LOAD_GLOBAL 3 (the actual name is co_names[3])
LOAD_FAST 3 (the actual name is co_varnames[3])
You can see that we have to distinguish between LOAD_FAST (i.e. load a local variable) and all other LOAD_X opcodes.
2. Getting The Right Name
When an error occurs, we need to go through the stacktrace/traceback until we find the frame in which the error occurred. From the frame we then get the code object with the list of all names and instructions, extract the instruction and argument that led to the error and thus the name.
We retrieve the traceback with sys.exc_info()[2]. The actual frame and traceback we are interested in is the very last one (this is what you can read in the line Traceback (most recent call last): whenever a runtime error occurs):
tb = sys.exc_info()[2] # get the traceback
while tb.tb_next is not None:
tb = tb.tb_next
This traceback object then contains two information of importance to us: the frame tb_frame and the instruction pointer tb_last where the error occurred. From the frame we then extract the code object:
instr_pos = tb.tb_lasti # the index of the "current" instruction
frame = tb.tb_frame
code = frame.f_code # the code object
Since the byte encoding the instruction can change with different Python versions, we want to get the human-readable form, which is more stable. We need that so that we can distinguish between local variables all others:
instruction = opcode.opname[code.co_code[instr_pos]]
arg = code.co_code[instr_pos + 1]
if instruction == 'LOAD_FAST':
return code.co_varnames[arg]
else:
return code.co_names[arg]
3. Caveat
If the code object uses more than 255 names, a single byte will no longer be enough as index into the tuples with all names. In that case, the bytecode allows for an extension prefix, which is not taken into account here. But for most code objects, this should work just fine.
As mentioned in the beginning, this is a rather hacky method that is based on internals of Python that might change (although this is rather unlikely). Nonetheless, it is fun taking Python apart this way, isn't it ;-).

How do I call globals() from another imported function in Python?

I am currently developing an automated function tester in Python.
The purpose of this application is to automatically test if functions are returning an expected return type based on their defined hints.
Currently I have two test functions (one which fails and one which passes), along with the rest of my code in one file. My code utilizes the globals() command in order to scan the Python file for all existing functions and to isolate user-made functions and exclude the default ones.
This initial iteration works well. Now I am trying to import the function and use it from another .py file.
When I run it in the other .py file it still returns results for the functions from the original file instead of the new test-cases in the new file.
Original File - The Main Application
from math import floor
import random
#declaring test variables
test_string = 'test_string'
test_float = float(random.random() * 10)
test_int = int(floor(random.random() * 10))
#Currently supported test types (input and return)
supported_types = ['int', 'float', 'str']
autotest_result = {}
def int_ret(number: int) -> str:
string = "cactusmonster"
return string
def false_test(number: int) -> str:
floating = 3.2222
return floating
def test_typematching():
for name in list(globals()):
if not name.startswith('__'):
try:
return_type = str((globals()[name].__annotations__)['return'])
autotest_result.update({name: return_type.replace("<class '", "").replace("'>", "")})
except:
continue
for func in autotest_result:
if autotest_result[func] != None:
this_func = globals()[func].__annotations__
for arg in this_func:
if arg != 'return':
input_type = str(this_func[arg]).replace("<class '", "").replace("'>", "")
for available in supported_types:
if available == input_type:
func_return = globals()[func]("test_" + input_type)
func_return = globals()[func]("test_" + input_type)
actual_return_type = str(type(func_return)).replace("<class '", "").replace("'>", "")
if actual_return_type == autotest_result[func]:
autotest_result[func] = 'Passed'
else:
autotest_result[func] = 'Failed'
return autotest_result
Test File - Where I Am Importing The "test_typematching()" Function
from auto_test import test_typematching
print(test_typematching())
def int_ret_newfile(number: int) -> str:
string="cactusmonster"
# print(string)
# return type(number)
return string
Regardless if I run my main "auto_test.py" file or the "tester.py" file, I still get the following output:
{'int_ret': 'Passed', 'false_test': 'Failed'}
I am guessing this means that even when I am running the function from auto_test.py on my tester.py file it still just scans itself. I would like it to scan the file where the function is currently being called. For example, I expect it to test the int_ret_newfile function of tester.py.
Any advice or help would be much appreciated.
globals() is a bit of a misnomer. It gets the calling module's __dict__. (Python's true "global" namespace is actually builtins.)
How can globals() get its caller's __dict__ when it's defined in the builtins module? Here's a clue:
PyObject *
PyEval_GetGlobals(void)
{
PyThreadState *tstate = _PyThreadState_GET();
PyFrameObject *current_frame = _PyEval_GetFrame(tstate);
if (current_frame == NULL) {
return NULL;
}
assert(current_frame->f_globals != NULL);
return current_frame->f_globals;
}
globals() is one of those builtins that's implemented in C (in CPython), but you get the gist. It reads the frame globals from the current stack frame, so in Python,
import inspect
inspect.currentframe().f_globals
would do the same thing as globals(). But you can't just put this in a function and expect it to work the same way, because calling it would add a stack frame, and that frame's globals depends on the function's .__globals__ attribute, which is set to the .__dict__ of the module that defined it. You want the caller's frame.
def myglobals():
"""Behaves like the builtin globals(), but written in Python!"""
return inspect.currentframe().f_back.f_globals
You could do the same thing in test_typematching. But walking up the stack to the previous frame like that is a weird thing to do. It can be surprising and brittle. It amounts to passing the caller's frame as an implicit hidden argument, something that normally is not supposed to matter. Consider what happens if you wrap it in a decorator. Now which stack frame are you getting the globals from?
So really, you should be passing in globals() as an explicit argument to test_typematching(), like test_typematching(globals()). A defined and documented parameter would be much less confusing than implicit introspection. "Explicit is better than implicit".
Still, Python's standard library does do this kind of thing occasionally, with globals() itself being a notable example. And exec() can use the current namespace if you don't give it a different one. It's also how super() can now work without arguments in Python 3. So stack frame inspection does have precedent for this kind of use case.

How to add a global symbol that can be bound by Python compiler?

This is my first question so please be nice :) I am rather new to Python but I am very experienced in other programming languages (e.g. C++).
UPDATE 2 - Solution Found
Thanks everyone for helping :) As the solution is "hidden" in comments I will repost it here.
Instead of
file_symbols = {}
the variable local_symbol must initially be added to the file_symbols dictionary:
file_symbols = { "local_symbol" : local_symbol }
For anyone reading this: all variable / class names posted here are not to be understood as actual useful names as these examples are synthetic in nature ;)
Well... now I have to figure out the FULL meaning of:
exec compiled_code in file_symbols
So far I thought it would do nothing more than updating the dictionary file_symbols with the symbols found in compiled_code.
But it actually does a bit more as it seems! :)
UPDATE 1
Ok, my sample project below seems to be too simple to show the actual problem. Anyway, thanks for your already provided support! :)
In fact I want to first compile multiple *.py files which need access to a local symbol (class instance). All symbols coming from these compiled files shall be collected and then be used as an environment for OTHER code objects.
So I really need to do this
(note the following code shows the concept, not actual executable code):
class Functions:
(...)
global_symbols = {}
local_symbol = Functions()
# note that the external files need to access local_symbol to call its functions!
for file in external_files:
code = file.load()
compiled_code = compile(code, "<string>", "exec")
file_symbols = {}
exec compiled_code in file_symbols
global_symbols.update(file_symbols)
some_code = another_file.load()
compiled_code = compile(some_code, "<string>", "exec")
exec(compiled_code, global_symbols)
In this example the line
exec compiled_code in file_symbols
produces a NameError() - because there is no way they could access local_symbol as it is not defined anywhere in the external files although it shall be used!
So the question is how to provide access to local_symbol for the external_files so that they can call the instance's functions??
My import hook solution that some of you regard as "hack" was the only working solution so far. I would love to use a simpler one if there is any!
Thanks again :)
My initial question was this:
So here we go. What I intend to do is advanced stuff and I did not find a solution to my problem neither here nor anywhere else.
Assume the following code in Python (2.6.x / 2.7.x):
class Functions:
def __init__(self):
(...)
def func_1(...):
(...)
def func_2(...):
(...)
(...)
def func_n(...):
(...)
functions = Functions()
code = loadSomeFile(...)
compiled_code = compile(code, "<string>", "exec")
(...)
global_env = {}
local_env = {"func":functions}
exec(compiled_code, global_env, local_env)
where code in the example above is loaded from a file with a content that might look like this:
import something
(...)
def aFunction(...):
a = func.func_1(...)
b = func.func_2(...)
return a * b
(...)
aFunction()
Please note that (...) in the code above means that there might be more code that I left out for the sake of simplicity.
The problem I encounter in my example is that the compiler raises an error for this line:
compiled_code = compile(code, "<string>", "exec")
I will get this error: NameError("global name 'func' is not defined")
This error is totally understandable as the compiler can't bind to any global symbol with the name "func". But I still want to compile the code this way.
So the obvious question is:
How can I define global symbols that can be used by the compiler for compile() statements so that the compiler will bind any "unknown" symbol to an object of my choice?
In my example I would like to define a global symbol func that is bound to an instance of class Functions so that the compiler will find this symbol when compiling code which makes use of func as seen in the example above.
So how can this be accomplished?
Important:
Please note that I am aware that directly executing the code using exec(...) would fix the compilation problem because the dict local_env in the example above would provide the symbol that is required for successful execution. HOWEVER I can't do it this way because the code that shall be compiled is not small at all. It might consist of hundreds of code lines and this code is also not executed only once but many many times.
So for performance reasons I really need to compile the code rather than directly executing it.
Thanks for helping me :)
Don't provide separate globals and locals dicts to exec. That causes the executed code to behave as if it's embedded in a class definition. That means that any variable lookups in functions defined in the executed code bypass locals.
>>> exec("""
... def f():
... print a
... f()""", {}, {"a": 3})
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
File "<string>", line 4, in <module>
File "<string>", line 3, in f
NameError: global name 'a' is not defined
>>> exec("""
... def f():
... print a
... f()""", {"a": 3})
3
Just pass a globals dict.
The simple explanation is that you pass in func in the local namespace. aFunction does not have access to the locals you passed in (it has its own locals). All aFunction has access to is its own locals and its module's globals. func is in neither of these and so the function call fails.
Most normal modules work with their globals and locals as the same namespace (you can check this out yourself assert globals() is locals()). This is why you can define things at the module level and have them available to any defined functions (all names in a module are automatically global).
To make this work you need to make locals and globals the same dict, or just not pass locals at all. If you don't want globals to be mutated, then just copy globals and then add func to it.
src = """
def aFunction():
a = func.func_1()
b = func.func_2()
return a + b
value = aFunction()
"""
class Functions:
def func_1(self):
return "first"
def func_2(self):
return "second"
functions = Functions()
compiled_code = compile(src, "<string>", "exec")
global_env = {}
local_env = {"func":functions}
namespace = dict(global_env)
namespace.update(local_env)
exec(compiled_code, namespace)
print(namespace["value"])
it is an interesting question, thanks for posting it. I've been taking a look at how to change the globals table in compile time. Apparently, you can call the __import__() function directly and:
pass your globals in order to determine how to interpret the name in a package context.
Source: Package documentation
Well, obviously it works by simply adding (and potentially removing - if using multiple "func" instances) the instance to sys.modules:
sys.modules["func"] = functions
(...)
compiled_code = compile(code, "<string>", "exec")
The complete and working solution including an importer hook (which intercepts "import func" lines in source code files) would look like this:
import sys
class Functions:
def __init__(self):
(...)
def func_1(...):
(...)
def func_2(...):
(...)
(...)
def func_n(...):
(...)
functions = Functions()
code = loadSomeFile(...)
hook_name = "func"
class ImporterHook:
def __init__(self, path):
if path != hook_name:
raise ImportError()
def find_module(self, fullname, path=None):
return self
def load_module(self, path):
if sys.modules.has_key(path):
return sys.modules[path]
else:
sys.modules[path] = functions
return functions
sys.path_hooks.append(ImporterHook)
sys.path.insert(0, hook_name)
compiled_code = compile(code, "<string>", "exec")
(...)
exec(compiled_code)
Not so hard as it seems :) For more information see here:
https://www.python.org/dev/peps/pep-0302/#specification-part-2-registering-hooks
and here:
https://pymotw.com/2/sys/imports.html
THANKS :)

Python: Help with UnboundLocalError: local variable referenced before assignment

I keep getting this error for a portion of my code.
Traceback (most recent call last):
File "./mang.py", line 1688, in <module>
files, tsize = logger()
File "./mang.py", line 1466, in logger
nl = sshfile(list, "nl")
UnboundLocalError: local variable 'sshfile' referenced before assignment
I haven't put the code up cause it goes back and forth between functions. I'm wondering if anyone could tell me why python is spitting this error? sshfile is not a variable it's a class.
You probably haven't imported the file which contains the definition of sshfile, or you need to qualify the class name with the package name. It depends on how you imported it.
What package does it come from? Where is it defined?
Update
For anyone else reading this, after a discussion in the comments it turned out that the problem was that the name sshfile had been used further down in the function as a variable name, like this:
class sshfile:
pass
def a():
f = sshfile() # UnboundLocalError here
sshfile = 0
a()
The solution is to not use a variable name that hides a class name that you need to use.

Categories