Is it possible to do something like this?
def loadModules():
import time
from myModule import *
def runFunction():
try:
print str(time.time())
print myFunction() # myFunction is in myModule (myModule.myFunction)
except NameError:
raise RuntimeError("Module was not initialized. Call loadModules() first.")
if (__name__ == "__main__"):
# this should fail
try:
runFunction()
except RuntimeError:
print "Exception raised as expected."
loadModules()
runFunction() # it should work now
This will not work as expected because importing the modules inside the loadModules function will not declare them at a file level.
For modules like time I could add a global time statement after the import. However, how can I accomplish this for a situation where the items imported are unknown, as in from myModule import *? I won't automatically know the name of every function in myModule. And even if I did, that'd be an ugly global statement.
Essentially, can I basically take all local variables and make them global?
EDIT: This seemed to work in test code:
def test():
import time
global time
print "Inside test function: %s" % str(time.time())
test()
print "outside function: %s" % str(time.time())
This also worked:
def test():
from time import time
global time
print "Inside test function: %s" % str(time())
test()
print "outside function: %s" % str(time())
This however did not work:
def test():
import time
print "Inside test function: %s" % str(time.time())
test()
print "outside function: %s" % str(time.time())
This is a horrible idea, even if it could ever work, which it couldn't.
Putting a global statement after the import will have exactly zero effect. The only thing that does is mark that name as global within the current scope. Once the function returns, the caller will still have no knowledge of the imported names.
In any case, you shouldn't ever be using from MyModule import * anyway.
Related
I want to keep track of the last time my python program printed something to the console.
I created this function:
def updateLastPrintTime():
global lastPrintTime
lastPrintTime = time.time()
And I'm calling it after each print statement.
This works fine, however, I have a lot of print statements and I want to update lastPrintTime after each and every printing.
If print was not a built in function, this is what I would do:
def print():
updateLastPrintTime()
# rest of 'print' code ...
But I can't figure out how to do that with a built-in function, especially since they are written in C.
Any help would be appreciated.
Based on this answer: overload print python
You could do something like this:
from __future__ import print_function
import time
last_print_time = time.time() # initialise global var
try:
import __builtin__
except ImportError:
# Python 3
import builtins as __builtin__
# overload the print function
def print(*args, **kwargs):
global last_print_time
last_print_time = time.time() # update variable
return __builtin__.print(*args, **kwargs) # print the message
You can assign the builtins print to another name and then you can override print
_print = print
def print(*args, **kwargs):
_print("Hello,", *args, **kwargs)
print("world!")
Alternatively, you can also get the builtins print from the builtins module e.g.
import builtins
def print(*args, **kwargs):
builtins.print("Hello,", *args, **kwargs)
print("world!")
I hope someone could help me with this problem I am having. So it looks pretty simple, I just wanted to get the variable that was set inside a Fabric task and wanted it to be called in another function. Global Variable seems to not work and I am relatively new to python fabric so any help would be appreciated.
from fabric.api import *
#task
def function_inside(name):
samplename = name.lower()
print("{}".format(samplename))
def another_function():
print "This is outside: " + samplename
another_funtion()
So after much time working on this primer script that I have, I just have a workaround.
from fabric.api import *
container={A:'',B:''}
#task
def first_func(var):
container['A']=var
#task
def second_func(var):
container['B']=var
#task
def main_func():
var1=container['A']
var2=container['B']
print "This is from first function: " + var1
print "This is from second function: " + var2
so when I execute the fabric it goes like this:
fab firs_func:John second_func:Angel main_func
But this is still a workaround and I would still like to know how we can call a variable from a task and pass it to a normal function that is not a tasks.
I don't have idea about fabric but i can help you for global variable
try this:-
def function_inside(name):
global samplename
samplename = name.lower()
print("{}".format(samplename))
def another_function():
print ("This is outside: " + samplename)
#execute as below
function_inside("HELLO")
another_function()
I would suggest you to add your "global" variable in Fabric's env dictionary. This dictionary has its state kept during your Python script's lifecycle. Given that, your code would look like:
from fabric.api import *
from fabric.tasks import execute #The 'execute' function is quite useful
when you want to tell Fabric to execute a
function as a Fabric task
#No need to annotate your function
def function_inside(name):
env.samplename = name.lower()
print("{}".format(env.samplename))
def another_function():
print "This is outside: " + env.samplename
execute(function_inside, "Foo")
execute(another_function)
And then, in your shell:
python your_script.py
What about running tasks synchronously and wait for the result?
# #task
def first_func(var):
# process var
return var
# #task
def second_func(var):
# process var
return var
#task
def main_func():
var1=first_func(container['A'])
# or var1=first_func(var1)
var2=second_func(container['B'])
# or var2=first_func(var2)
print "This is from first function: " + var1
print "This is from second function: " + var2
Why does the value of my_string not change?
I'm running two threads from two different modules, and module 2 accesses the "set_string" of module 1 in order to change the value of "my_string", but when module 1 prints the string, its empty.
First module:
from threading import Thread
import Module2 as M2
import time
my_string = ""
def set_string(string):
global my_string
my_string = string
def mainloop1():
global my_string
while True:
print("Module 1: ", my_string)
time.sleep(1)
if __name__ == '__main__':
thread = Thread(target=M2.mainloop2)
thread.start()
mainloop1()
Second module:
import Module1 as M1
import time
import random
def mainloop2():
while True:
string = str(random.randint(0, 100))
print("Module 2: ", string)
M1.set_string(string)
time.sleep(1)
It's because the methods are implemented in different modules and there are no truly global variables in python; the set_string referenced in Module2 is updating the my_string variable in its globals()['M1'] name where-as Module1 is updating the my_string variable stored directly in globals()['my_string'].
Note that if you move your definition of mainloop2 into Module1, update the imports, and the Thread call then you get your expected behavior, indefinite execution order and all.
So I'm running into a problem where the try: except: mechanism doesn't seem to be working correctly in python.
Here are the contents of my two files.
pytest1.py
import pytest2
class MyError( Exception ):
def __init__( self, value ):
self.value = value
def __str__( self ):
return repr( self.value )
def func1():
raise MyError( 'This is an error' )
def func3():
pytest2.func2()
if __name__ == '__main__':
try:
func3()
except MyError, e:
print 'I should catch here.'
except:
print 'Why caught here?'
pytest2.py
from pytest1 import func1
def func2():
func1()
Executing the first file yields the following output:
$ python pytest1.py
Why caught here?
Basically, the exception isn't being caught. If I print out the exception type, it prints as <pytest1.MyError> instead of just <MyError>. I imagine that this is some weird cyclical reference thing, but it still seems like it should work.
The main python program is always imported as the module __main__.
When you import pytest2, it doesn't reuse the existing module because the originally imported module has the name __main__ not pytest2. The result is that pytest1 is run multiple times generating multiple exception classes. __main__.MyError and pytest1.MyError You end up throwing one and trying to catch the other.
So, don't try to import your main module from other modules.
This problem is caused by importing the script you are running as a module. This produces two separate copies of the module!
Another example:
module.py
import module
class Foo: pass
def test():
print Foo
print module.Foo
print Foo is module.Foo
if __name__ == '__main__': test()
main_script.py
import module
if __name__ == '__main__': module.test()
Result
>python main_script.py
module.Foo
module.Foo
True
>python module.py
__main__.Foo
module.Foo
False
Running python somefile.py creates a module called __main__, not somefile, and runs the code in somefile.py in that module. This is why if __name__ == '__main__': is used to check if this file is being run as a script or imported from some other file.
... at a guess, you have a namespace problem which is producing a different exception.
Try replacing
except:
print 'Why caught here?'
with
except Exception, e:
print e
This may tell you more about what went wrong.
I am trying to pass current object reference i.e. self to the Timer class of timeit module but somehow i am not getting it how to do it. I tried to find it in timeit documentation but i could not find it. I have attached my code with this question.
from timeit import Timer
import time
import math
class PollingDemo(Thread):
def __init__(self):
pass
def looper(self):
while 1:
try:
T = Timer("self.my_func()")
#T = Timer("polling.my_func()", "from __main__ import polling")
time_elapsed = T.timeit(1)
if math.ceil(time_elapsed) == 1:
print "Process is sleeped for 1 sec"
time.sleep(1)
except KeyboardInterrupt:
return
def my_func(self):
pass
if __name__ == '__main__':
polling = PollingDemo()
polling.looper()
In this example i have tried to call my_func() method of PollingDemo class through Timer class timeit() method but i am getting "NameError: global name 'self' is not defined" error. if we tried to access that object through main it works (Next commented line works perfectly). Can someone please why is this behavior so.
Thanks in advance.
Don't use a string, Timer also accepts callables, so pass a reference bound to self directly, i.e.
T = Timer(self.my_func)
(just the reference, don't call it).
If you need more complex setup, again wrap it in a function or method and pass that method.
If you need to pass arguments, just use partial from functools:
import functools
import timeit
def printme(msg):
print msg
print "Timing: %f" % timeit.timeit(functools.partial(printme, "Hello world"))