I have the function changecheck() which is defined in a different module(called check.py). I want to pass changeId as a parameter to this function.
I am calling this function from the file test.py.
I am unable to understand the reason why this parameter is not being passed correctly.
check.py
returnVal = changecheck(changeInfoItem['changeId'])
In a differnt module test.py
def changecheck(changeId):
print changeId //nothing gets printed
This should fix your problem:
In the module test.py
def changecheck(changeId):
print changeId
In the module check.py
import test
returnVal = test.changecheck(changeInfoItem['changeId'])
You have to do this:
import check
returnVal = check.changecheck(changeInfoItem['changeId'])
Related
I have some code in multiple files like so:
A main module:
import TC1
import TC2
Some test case modules, which look like:
testcase = "Test Case 1"
successmessage = "Specific Success Message for Test Case 1"
errormessage = "Specific Error Message for Test Case 1"
# Run test
if pageLoaded == pageExpected:
testresult = 0
logresults()
else:
testresult = 1
logresults()
And a log results module:
def logresults():
print("Test Results for", testcase,)
if testresult == 0
print(testcase, "Passed with", successmessage)
else:
print(testcase, "Failed with", errormessage)
How can I pass variables from each test case to logresults, and have it print the results of each test case as it is run?
I see two issues with your code.
First, if you import a module with a function that works on globals, it will search for globals that share a namespace. For example, if you have a logresultsmodule with a function logresults and you import it, it will only run on variables that look like this: logresultsmodule.variable
To fix this problem, you will have to change the signature of the function to
def logresults(testresult, testcase, successmessage, errormessage): ...
and pass the corresponding variables.
The second problem is you call logresults inside a conditional where there is a chance that the testresult variable hasn't been defined yet.
First evaluate the conditional, and then call logresults.
from logresultsmodule import logresults
{code that defines testcase, successmessage, errormessage}
if pageLoaded == pageExpected:
testresult = 0
else:
testresult = 1
logresults(testresult, testcase, successmessage, errormessage)
So now whenever you import a testcase, the code will run automatically and print the result message.
I want python to show me which function has been executed and from what file... so I have the following as test1.py
import sys,os, test2
def some_function():
print (sys._getframe().f_code.co_name +" "+ os.path.basename(__file__) , 'executed')
print (test2.function_details(), 'executed')
test2.py is:
import sys,os
def function_details():
return sys._getframe().f_code.co_name + " " +os.path.basename(__file__)
now when I run it
import test1
test1.some_function()
I get the following output:
('some_function test1.pyc', 'executed')
('function_details test2.pyc', 'executed')
When I try to make a function for calling the file and function of the executed, it tells me the sub function I made instead of the original.
My question is how do I modify test2.py so it will output
('some_function test1.pyc', 'executed')
('some_function test1.pyc', 'executed')
So there are two issues with function_details:
The current frame is function_details so you need to go up one frame to get to the calling frame. To do this you pass 1 to sys._getframe.
__file__ is the name of the current file for whatever module you happen to be in (if defined), this needs to be replaced with the co_filename attribute of the f_code object associated with the correct frame.
Correcting both of these things, we redefine function_details as:
def function_details():
code_obj = sys._getframe(1).f_code
return " ".join([code_obj.co_name, os.path.basename(code_obj.co_filename)])
Which produces the desired result. In my opinion, the inspect module accomplishes this same thing far better than using sys._getframe directly. Here's the new function_details written using inspect:
import inspect
def function_details():
frame = inspect.getouterframes(inspect.currentframe())[1]
return " ".join([frame[3], os.path.basename(frame[1])])
I have a server.py which contains a function and other files like requestor1.py requestor2.py .... requestorN.py
Server.py contains a function :
def callmeforhelp()
return "I am here to help you out!"
and requestor1.py file calls the function callmeforhelp() and it has the imports needed to call the function from server.py
Is there a way my server.py knows which file is calling it?
Something similar like below :
When requestor1.py calls the function, then :
def callmeforhelp()
print "Now I am being called by : "+caller // caller must contain the value as requestor1.py or even full path of requestor1.py
return "I am here to help you out!"
Try it in your server file:
import inspect
def callmeforhelp():
result = inspect.getouterframes(inspect.currentframe(), 2)
print("Caller is: " + str(result[1][1]))
Here is a way to get at the caller's local attributes:
import sys
def callmeforhelp():
print("Called from", sys._getframe(1).f_locals['__file__'])
This is a feature of CPython and is not guaranteed to be present in other language implementations.
In C++, I can print debug output like this:
printf(
"FILE: %s, FUNC: %s, LINE: %d, LOG: %s\n",
__FILE__,
__FUNCTION__,
__LINE__,
logmessage
);
How can I do something similar in Python?
There is a module named inspect which provides these information.
Example usage:
import inspect
def PrintFrame():
callerframerecord = inspect.stack()[1] # 0 represents this line
# 1 represents line at caller
frame = callerframerecord[0]
info = inspect.getframeinfo(frame)
print(info.filename) # __FILE__ -> Test.py
print(info.function) # __FUNCTION__ -> Main
print(info.lineno) # __LINE__ -> 13
def Main():
PrintFrame() # for this line
Main()
However, please remember that there is an easier way to obtain the name of the currently executing file:
print(__file__)
For example
import inspect
frame = inspect.currentframe()
# __FILE__
fileName = frame.f_code.co_filename
# __LINE__
fileNo = frame.f_lineno
There's more here http://docs.python.org/library/inspect.html
Building on geowar's answer:
class __LINE__(object):
import sys
def __repr__(self):
try:
raise Exception
except:
return str(sys.exc_info()[2].tb_frame.f_back.f_lineno)
__LINE__ = __LINE__()
If you normally want to use __LINE__ in e.g. print (or any other time an implicit str() or repr() is taken), the above will allow you to omit the ()s.
(Obvious extension to add a __call__ left as an exercise to the reader.)
You can refer my answer:
https://stackoverflow.com/a/45973480/1591700
import sys
print sys._getframe().f_lineno
You can also make lambda function
I was also interested in a __LINE__ command in python.
My starting point was https://stackoverflow.com/a/6811020 and I extended it with a metaclass object. With this modification it has the same behavior like in C++.
import inspect
class Meta(type):
def __repr__(self):
# Inspiration: https://stackoverflow.com/a/6811020
callerframerecord = inspect.stack()[1] # 0 represents this line
# 1 represents line at caller
frame = callerframerecord[0]
info = inspect.getframeinfo(frame)
# print(info.filename) # __FILE__ -> Test.py
# print(info.function) # __FUNCTION__ -> Main
# print(info.lineno) # __LINE__ -> 13
return str(info.lineno)
class __LINE__(metaclass=Meta):
pass
print(__LINE__) # print for example 18
wow, 7 year old question :)
Anyway, taking Tugrul's answer, and writing it as a debug type method, it can look something like:
def debug(message):
import sys
import inspect
callerframerecord = inspect.stack()[1]
frame = callerframerecord[0]
info = inspect.getframeinfo(frame)
print(info.filename, 'func=%s' % info.function, 'line=%s:' % info.lineno, message)
def somefunc():
debug('inside some func')
debug('this')
debug('is a')
debug('test message')
somefunc()
Output:
/tmp/test2.py func=<module> line=12: this
/tmp/test2.py func=<module> line=13: is a
/tmp/test2.py func=<module> line=14: test message
/tmp/test2.py func=somefunc line=10: inside some func
import inspect
.
.
.
def __LINE__():
try:
raise Exception
except:
return sys.exc_info()[2].tb_frame.f_back.f_lineno
def __FILE__():
return inspect.currentframe().f_code.co_filename
.
.
.
print "file: '%s', line: %d" % (__FILE__(), __LINE__())
Here is a tool to answer this old yet new question!
I recommend using icecream!
Do you ever use print() or log() to debug your code? Of course, you
do. IceCream, or ic for short, makes print debugging a little sweeter.
ic() is like print(), but better:
It prints both expressions/variable names and their values.
It's 40% faster to type.
Data structures are pretty printed.
Output is syntax highlighted.
It optionally includes program context: filename, line number, and parent function.
For example, I created a module icecream_test.py, and put the following code inside it.
from icecream import ic
ic.configureOutput(includeContext=True)
def foo(i):
return i + 333
ic(foo(123))
Prints
ic| icecream_test.py:6 in <module>- foo(123): 456
To get the line number in Python without importing the whole sys module...
First import the _getframe submodule:
from sys import _getframe
Then call the _getframe function and use its' f_lineno property whenever you want to know the line number:
print(_getframe().f_lineno) # prints the line number
From the interpreter:
>>> from sys import _getframe
... _getframe().f_lineno # 2
Word of caution from the official Python Docs:
CPython implementation detail: This function should be used for internal and specialized purposes only. It is not guaranteed to exist in all implementations of Python.
In other words: Only use this code for personal testing / debugging reasons.
See the Official Python Documentation on sys._getframe for more information on the sys module, and the _getframe() function / submodule.
Based on Mohammad Shahid's answer (above).
I've got a function here for running an external python script in another process. m is the Multiprocessing module
def run(app,WindowOffX,WindowOffY,WindowWidth,WindowHeight):
try:
exec("import Programs."+app+".main as Foo")
Foo.init()
p = m.Process(target=Foo.main(WindowOffX,WindowOffY,WindowWidth,WindowHeight))
except ImportError:
print("That app doesn't exist!!! O.O")
But this generates NameError: global name 'Foo' is not defined. Can someone help?
Ha, the problem is that python doesn't know your exec statement defines Foo, so it tries to look it up as a global. To clue it in, try this:
try:
Foo = None
exec("import Programs."+app+".main as Foo")
Foo.init()
Incidentally, here's how you can do what you're after without using exec:
Foo = __import__("Programs."+app+".main")