For sqldf method of pandasql package, there is a "session/environment variables", could be locals() or globals(), could anyone let me know what it is for? And any document reference when should we use locals(), and when should we use globals()?
https://github.com/yhat/pandasql/
Here is my code and wondering what things pandansql is looking for thorough locals()? And locals() means namespace inside method select_first_50?
def select_first_50(filename):
students = pandas.read_csv(filename)
students.rename(columns = lambda x: x.replace(' ', '_').lower(), inplace=True)
q = "select major, gender from studentstable limit 50"
#Execute your SQL command against the pandas frame
results = pandasql.sqldf(q.lower(), locals())
return results
locals() and globals() are python built-in functions that are used to return the corresponding namespace.
In Python , Namespace is a way to implement scope. So global namespace means global scope, so variables(names) defined there are visible throughout the module.
local namepsace is the namespace that is local to a particular function.
globals() returns a dictionary representing the current global namespace.
locals()'s return depends on where it is called, when called directly inside the script scope (not inside a particular function) it returns the same dictionary as globals() that is the global namespace. When called inside a function it returns the local namespace.
In pandasql , the second argument you need to pass is basically this namespace (dictionary) that contains the variables that you are using in the query. That is lets assume you create a DataFrame called a , and then write your query on it. Then pandasql needs to know the DataFrame that corresponds to the name a for this it needs the local/global namespace, and that is what the second argument is for.
So you need to decide what to pass in, example , if your DataFrame is only defined inside a function and does not exist in global scope, you need to pass in locals() return dictionary, If your DataFrame exists in global scope, you need to pass in result of globals() .
Related
A little easy problem:
exec("a=3")
print(a)
# This will print 3
If I use this:
def func():
exec("a=3")
print(a)
func()
# NameError: name 'a' is not defined.
What happened?How could I use exec() to assign it a value in a function?
Edit:I found a question with the same trouble but still didn't solved.
why do you want to do that?
I know using exec() is bad and unsafe.But recently I try to solve a OP's problem.I met it.
Python knows several kinds of scope: module global, function local, nonlocal closures, class body. Notably, scope resolution is defined statically at byte code compile time – most importantly, whether names refer to local/nonlocal or global scope cannot be changed.
Of these scopes, only global scope is guaranteed to behave similar to a dict, and as such writeable. The local/nonlocal scope is generally not writeable, and new variables cannot be added to it.
exec will write to the global scope if locals is not passed in; globals must then explicitly be set to its default of globals().
def func():
exec("a='exec'", globals()) # access only global scope
print(a)
a = 'global'
func() # prints exec
However, once a name is local to a function, exec cannot modify it.
def func():
a = 'local' # assignment makes name local
exec("a='exec global'", globals())
exec("a='exec locals'", globals(), locals())
print(a)
a = 'global'
func() # prints local
While a dict-like representation of local/nonlocal scope exists, the interpreter is not required to honour changes to it.
locals()
Update and return a dictionary representing the current local symbol table. Free variables are returned by locals() when it is called in function blocks, but not in class blocks. Note that at the module level, locals() and globals() are the same dictionary.
Note: The contents of this dictionary should not be modified; changes may not affect the values of local and free variables used by the interpreter.
Even though exec does take locals as a dict, these are not treated like function locals/nonlocals. Attempts to modify the default locals (the result of locals()) are not defined.
exec()
... If globals and locals are given, they are used for the global and local variables, respectively. If provided, locals can be any mapping object. Remember that at module level, globals and locals are the same dictionary. If exec gets two separate objects as globals and locals, the code will be executed as if it were embedded in a class definition.
Note: The default locals act as described for function locals() below: modifications to the default locals dictionary should not be attempted. ...
execute help(exec) in your python3 REPL, you will get the following docuement:
Help on built-in function exec in module builtins:
exec(source, globals=None, locals=None, /)
Execute the given source in the context of globals and locals.
The source may be a string representing one or more Python statements
or a code object as returned by compile().
The globals must be a dictionary and locals can be any mapping,
defaulting to the current globals and locals.
If only globals is given, locals defaults to it.
so there are at least 2 options to provide the value of argument 'a':
assign a value to the variable 'a' in the module's global scope:
a = 1
def func():
exec("global a;a=3")
print(a)
pass a customized global or local context to exec:
def func():
my_context = {'a': 1}
exec("a=3", None, my_context)
print(my_context['a'])
NOTE: DONT USE eval or exec IN YOUR SERIOUS CODE UNLESS YOU KNOW WHAT YOU ARE DOING.
EDIT NOTE
the following solution(2th solution mentioned in the comments) wont work:
def func():
a = 1
exec("a=3")
print(a) # still get 1 here
Suppose I wrote a function that returns a function:
def my_func(word):
def say():
print(word)
return say
f = my_func("Hello!")
print(f)
<function my_func.<locals>.say at 0x7f39fb454840>
What is the meaning of <locals> here?
Locals and globals are symbol tables. When you run a python script, a list of all local identifiers i.e. symbols with scope limited to the current block (For e.g. a function) is maintained by the interpreter. This is what <locals> refers to in your output. Similarly, there is a list of all global identifiers called globals.
You can call locals() and globals() at any point in your code to get the corresponding symbol tables in a dictionary format
How do you dynamically set variables as global in Python 3 functions?
Something like this:
def func1(i):
global i
#Some operation on i
How would I get the global variable to set whatever pre-existing variable is passed into the function? Such that:
func1(foo)
Would preform the operation on the variable foo globally rather than creating a new global variable called i?
If I got it right, your problem is:
I've bound a name to some object at module level; now I want to write a function that changes the binding of that global name to another object passed as an argument to the function.
In Python global names can be referenced inside a function (provided that you don't bind another object to the same name), but to change their binding you must first declare those names as global. The reason is simple: by default all names bound inside a function have function scope.
GLOBAL_NAME = 12
ANOTHER_GLOBAL_NAME = 50
def func(value):
global GLOBAL_NAME
GLOBAL_NAME = value
print(GLOBAL_NAME, ANOTHER_GLOBAL_NAME)
When you call func(33), GLOBAL_NAME will be bound to the object 33. ANOTHER_GLOBAL_NAME is just a reference to a global name; since that name is not bound inside the function, Python look for that name in the global scope.
For further insights on Python scope enclosing you can refer to the Python documentation on the global statement, to PEP-0227 and to PEP-3104.
A module holds a dictionary to keep track of itscontext, such as the names defined at some point of the execution. This dictionary can be accessed through vars(module) (or module.__dict__) if module was imported, or by a call to the locals built-in function in the module itself:
Update and return a dictionary representing the current local symbol table.
But I found myself a bit confused, when I tried accessing the locals dictionary from a function. The output of a script containing only the following is an empty dictionary:
def list_locals():
print(locals())
list_locals()
But on the other hand, if a script contains exclusively the following, the output is the expected dictionary, containing __name__, __doc__ and the other module-level variables:
print(locals())
So, when is the content of the locals dictionary set?
In addition, what does "update" mean in the definition of the locals function?
The namespace of a module is the global namespace, accessed through globals(). There is no separate locals namespace, so locals(), outside of functions, just returns the global namespace.
Only functions have a local namespace. Note that locals() is a one-way reflection of that namespace; the CPython implementation for functions is highly optimised and you can't add or alter local variables through the locals() dictionary. The dictionary returned by locals() is updated whenever the namespace has changed between calls to that function.
Note also that things like list / dict / set comprehensions, generator expressions and class bodies are in reality executed as functions too, albeit with different namespace rules. In such contexts locals() will also return the separate function local namespace.
If you call locals() more than once during the same function call, it will return the same dictionary.
>>> def f():
... d = locals()
... assert 'd' not in d
... locals()
... assert 'd' in d
... assert d is locals()
... print(d)
...
>>> f()
{'d': {...}}
"Update" in this case means that the contents of this dictionary are updated to reflect the current scope of local variables that exist, but if you kept a reference to this dictionary then that dictionary will still be used.
Notice also that the locals dictionary doesn't contain a key for 'f', even though you could have accessed it during the course of the function. In case it's not obvious, that's a global, not a local.
I'm trying to import a function from another module; however, I can't use import because the module's name needs looking up in a list.
If I try to call the imported function ExampleFunc normally I get:
NameError: global name 'ExampleFunc' is not defined
However; if I explicitly tell python to look in locals, it finds it.
File module.py
def ExampleFunc(x):
print x
File code.py
def imprt_frm(num,nam,scope):
for key, value in __import__(num,scope).__dict__.items():
if key==nam:
scope[key]=value
def imprt_nam(nam,scope):
imprt_frm("module",nam,scope)
def MainFunc(ary):
imprt_nam("ExampleFunc",locals())
#return ExampleFunc(ary) #fails
return locals()["ExampleFunc"](ary) #works
MainFunc("some input")
The locals() dictionary is but a reflection of the actual locals array. You cannot add new names to the locals through it, nor can you alter existing locals.
It is a dictionary created on demand from the actual frame locals, and is one-way only. From the locals() function documentation:
Note: The contents of this dictionary should not be modified; changes may not affect the values of local and free variables used by the interpreter.
Function locals are highly optimised and determined at compile time, Python builds on not being able to alter the known locals dynamically at runtime.
Rather than try and stuff into locals directly, you can return the one object from the dynamic import. Use the importlib module rather than __import__ here:
import importlib
def import_frm(module_name, name):
module = importlib.import_module(module_name)
return getattr(module, name)
then just assign to a local name:
def MainFunc(ary):
ExampleFunc = import_from('module' , 'ExampleFunc')
ExampleFunc(ary)