My real scenario needs to create global variables dynamically from within a function defined in a library so it can be reused for many projects. The function can be either a method in a base class or a global function.
For the sake of simplicity, consider the following a trivial example. I know the global variables are in file or module scope.
# mylib.py
class Parent:
def __init__(self, var_name):
self.__var_name__ = var_name
def create_global_variable(self, var_value):
globals()[self.__var_name__] = var_value
def clear_global_variables(self):
globals().clear()
# test.py
from mylib import Parent
class Child(Parent): pass
child = Child('temperature')
child.create_global_variable(100)
print(temperature) # NameError: name 'temperature' is not defined
child.clear_global_variables()
Is there any trick to bypass the restriction?
Edit
job()
will be reused in many projects.
def job(input, predicate, buffer_name):
globals()[buffer_name] = predicate(input)
return input
exp = fr"""
Squaring {job(2,lambda x: x*x, 'square')} equals to {square}
"""
print(exp)
Constraint: all buffering variables must be defined in f-string.
My real scenario needs to create global variables dynamically from within a function defined in a library so it can be reused for many projects. The function can be either a method in a base class or a global function.
For the sake of simplicity, consider the following a trivial example. I know the global variables are in file or module scope.
# mylib.py
class Parent:
def __init__(self, var_name):
self.__var_name__ = var_name
def create_global_variable(self, var_value):
globals()[self.__var_name__] = var_value
def clear_global_variables(self):
globals().clear()
# test.py
from mylib import Parent
class Child(Parent): pass
child = Child('temperature')
child.create_global_variable(100)
print(temperature) # NameError: name 'temperature' is not defined
child.clear_global_variables()
Is there any trick to bypass the restriction?
Edit
job()
will be reused in many projects.
def job(input, predicate, buffer_name):
globals()[buffer_name] = predicate(input)
return input
exp = fr"""
Squaring {job(2,lambda x: x*x, 'square')} equals to {square}
"""
print(exp)
Constraint: all buffering variables must be defined in f-string.
Share Improve this question edited Mar 21 at 20:27 D G asked Mar 21 at 19:55 D GD G 8298 silver badges15 bronze badges 12 | Show 7 more comments1 Answer
Reset to default 1If you really wanted to do this, I would suggest reading How do I create variable variables? and if you still wanted to proceed I woud think about something like this that will allow you to pass in the context you want to manipulate.
mylib.py:
class Parent:
def __init__(self, context, var_name):
self.__context__ = context
self.__var_name__ = var_name
def create_global_variable(self, var_value):
self.__context__[self.__var_name__] = var_value
def clear_global_variables(self):
if self.__var_name__ in self.__context__:
del self.__context__[self.__var_name__]
test.py:
from mylib import Parent
class Child(Parent):
def __init__(self, var_name):
super().__init__(globals(), var_name)
child = Child("temperature")
child.create_global_variable(100)
print(temperature)
child.clear_global_variables()
print(globals().get("temperature"))
child.clear_global_variables()
That should give you:
100
None
globals()
toChild(globals(), 'temperature')
but this seems like a bad idea. Perhaps if you explained your motivate a bit there might be a better alternative approach than using globals. – JonSG Commented Mar 21 at 20:10class Parent
or somedef mess_with_globals
in some module. The client code should just deal withglobals()
directly, if that's what it wants to do. but if there really was a good reason to do this, the only approach would be for the client to pass in their own globals as you suggested (aside from stack introspection hacks) – juanpa.arrivillaga Commented Mar 21 at 20:16Constraint: all buffering variables must be defined in f-string.
; WHY? – MatBailie Commented Mar 21 at 20:29