I need to add a variable "a" to global variables at runtime and be able to recover it anytime from the Item class. Result: I can't see it in the global variables.
Below there is an example. When I print the globals() I don't find the new "a" variable.
Specifically I need to be able to save the printVal result in a variable called "a", which I can consult in next call to this function.
In my final program I plan to add as many different variables as I want (variable and value).
Example:
class Item():
def printVal(self,value):
return value
def func(self):
userInput = input("Input string:")
if userInput!="0":
exec("a=self.printVal(\""+userInput+"\")",globals(),locals())
else:
return
print(globals())
self.func()
if __name__ == "__main__":
item = Item()
item.func()
If you jus watn to set a global variable with a name generated at runtime you do:
globals()[name] = val
by the way printVal method is dummy. Just return whtat it gets.
Related
What is the best way to append and clear the list deriv_position = [] from inside the function test?
I got NameError: name 'deriv_position' is not defined
class TestClass:
deriv_position = []
def test():
if len(deriv_position) > 0:
print("trade is open")
deriv_position.clear()
else:
print("trade is close")
deriv_position.append("1")
test()
In python, you refer to class variables using the self keyword. So inside the function, you can pass in self and then use it...
class TestClass:
def __init__(self):
self.deriv_position = []
def test(self):
if len(self.deriv_position) > 0:
print("trade is open")
self.deriv_position.clear()
else:
print("trade is close")
self.deriv_position.append("1")
TestClass().test()
You may find it worthwhile to read up on how classes work in Python:
https://docs.python.org/3/tutorial/classes.html#a-first-look-at-classes
Alternatively, if you are not using the class as a class (in your example, you are not), then there is no need for it. Just declare a global variable at the top of the file, and the test function just a function in the file.
To demonstrate what I want to do, here's a piece of code:
class CallOnce(object):
called=False
def web_service(cls,macid):
if cls.called:
print ("already called")
return
else:
# do stuff
print ("called once")
cls.called = True
return macid
To test our class, I proceed as follows:
for i in range(2):
macid = "123"
call_once_object = CallOnce()
call = call_once_object.web_service(macid)
print(call)
The expected result should be like this:
called once
123
already called
Except I got this as a result:
called once
123
called once
123
The idea is to store the value 123 only once in the call variable without using global variable.
cls.called is an attribute of the instance, not the class. Each time you create a new object, it gets its own attribute, which defaults to False.
If you want to share this among all the instances, you should use CallOnce.called, not cls.called.
BTW, the conventional name for the first argument of instance methods is self. cls is used for class methods.
So you're trying to save some state. What you could do is use an object instead.
class Test():
def __init__(self):
self.called = False
def call_me_maybe(self):
if (not self.called):
print('Hey, you called?')
self.called = True
else:
print("Stop calling me it's getting weird")
test = Test()
test.call_me_maybe() #-> Hey, you called?
test.call_me_maybe() #-> Stop calling me it's getting weird
You don't need a class for this. Functions can have their own attributes.
def web_service(macid):
if hasattr(web_service, 'called'):
print ("already called")
return
else:
# do stuff
print ("called once")
web_service.called = True
return macid
web_service(5)
web_service(6)
Output:
called once
already called
I have three functions that want to change a global variable and can't combine into one function, the way I know right now is keep define "global" keyword in each functions to be able to access global variable. Is there a better way to do the same thing with out keep redefining the global variable? for example:
def fn1(self):
global NUM
NUM = 1
print "fn1 = ", NUM
def fn2(self):
global NUM
NUM = 2
print "fn2 = ", NUM
def fn3(self):
global NUM
NUM = 3
print "fn3 = ", NUM
NUM = 0
fn1(NUM)
fn2(NUM)
fn3(NUM)
Thank you
Why don't you define another function, which changes the value of the global variable with the argument provided as parameter. And call this in rest of your function. For example :
var=None
class A:
def change(self,num):
global var
var = num
def first(self,num):
self.change(num)
def second(self,num):
self.change(num)
def third(self,num):
self.change(num)
a=A()
a.first(1)
print 'value of global variable',var
a.second(2)
print 'value of global variable',var
a.third(3)
print 'value of global variable',var
Otherwise, if the scope of your global variable is supposed to be confined within your class then declare it as a member of the class, and let the functions change it's value. For example :
class A:
def __init__(self):
self.var=None
print "default = ", self.var
def first(self,num):
self.var=num
print "fn1 = ", self.var
def second(self,num):
self.var=num
print "fn2 = ", self.var
def third(self,num):
self.var=num
print "fn3 = ", self.var
a=A()
a.first(1)
print 'value of variable',a.var
a.second(2)
print 'value of variable',a.var
a.third(3)
print 'value of variable',a.va
You can make the global variable a mutable class and then mutate in place.
global_dict = {"data": 1}
global_list = [1]
class MutableInt:
def __init__(self, value=1):
self.value = value
global_int = MutableInt()
This works, but personally I wouldn't call that any better. With the global it is at least 100% clear that you change a global variable. Best would be to change your architecture to not need any global variables.
it seems like the function are part of a class , based on the self keyword , if so they all can access class variable without the need of global keyword, if they are not part of a class you can:
define each function with a given parameter to the function and make that function return a value.
def func1(param_1):
#work on param_1
return param_1
This question already has answers here:
Calling a function of a module by using its name (a string)
(18 answers)
Closed 4 years ago.
I'm taking in an input from the user and storing it in a variable called videoType.
My question is, how do I take the string the user gives to videoType and convert that into a function name that I already have defined along with many others in python?
Ex.
user input: "get_MPEG()"
which is stored in videoType
And I would use that input as a function name.
I would create a dictionary. The keys to the dictionary are user inputs, the values are functions. Something like this:
def compliment():
print("You look nice today.")
def insult():
print("You look awful today.")
def default_function():
print("Sorry, I don't know what you mean")
functions = {
"compliment": compliment,
"nice": compliment, # aliased command
"insult": insult,
"mean": insult,
}
videoType = input("What shall I do? ")
functions.get(videoType, default_function)()
Whatever you do, do NOT directly convert the user's input to code. Consider what happens if the user inputs os.system('rm -rf' /) as the name of his function!
You can make a dictionary mapping function names to their corresponding functions:
def foo():
print('foo called')
def bar():
print('bar called')
exposed_functions = {
'foo': foo,
'bar': bar
}
if __name__ == '__main__':
user_input = 'foo' # Pretend the user passed you this string
function = exposed_functions[user_input]
function()
This approach may seem redundant but you probably don't want the user to pass in a function like exit() and shut down your interpreter or even something like __import__('os').system('rm -Rf --no-preserve-root /') and do more harm.
Therefore, a whitelist is your best choice. To make it simpler, you can create a decorator to do all of this for you:
import functools
exposed_functions = {}
def expose(*names):
def decorator(function):
for name in (names or [function.__name__]):
exposed_functions[name] = function
return function
return decorator
#expose() # `name` is automatically extracted out of the function
def foo():
print('foo called')
#expose('bar', 'baz') # binds to both `bar` and `baz`
def bar():
print('bar called')
if __name__ == '__main__':
user_input = 'baz' # Pretend the user passed you this string
function = exposed_functions[user_input]
function()
You can also use globals() dictionary to access all the defined top-level functions (as well as other objects) in a module
def hello():
print('hello')
videoType = input("Name a function")
globals()[videoType)()
code = "def foo(): return 'bar'"
def lol(code):
exec code
return foo
a = lol(code)
print a()
This works normally, but the problem starts when we don't know what the function in the string is called. If I can guarantee that the code will be small, with a single function, how can I return that function?
One solution I thought of was just requiring the function be called 'foo' etc, so I can just return that, but it feels ugly.
Thoughts?
You could do it by explicitly specifying dictionaries exec should use for the global and local execution context. Afterwards the one used for locals should have a single entry for the function object, which can be returned without knowing its name since it should be the only item defined in the dictionary:
from textwrap import dedent
import types
def lol(code):
globals_ = {"__builtins__": None} # no built-ins for safety
locals_ = {}
exec(code, globals_, locals_)
if len(locals_) != 1:
raise ValueError("code didn't define exactly one item")
value = locals_.popitem()[1] # get value of the one item defined
if type(value) != types.FunctionType:
raise ValueError("code didn't define a function")
return value # return function object that was defined
my_code = dedent("""
def foo():
return 'bar'
""")
a = lol(my_code)
print(a())