I'm a python begginer and I wanted to execute a method (A) with argues that will call another method (B) that will return values to (A).
I only can't reached the (B) method directly, for this I used a main. And so I can't retrieve (B)'s informations from (A)
My architecture looked like this :
Main Folder
|-> test_caller.py (A)
|-> called_file.py (B)
I want to call a method with argues from test_caller.py (main method), that will execute method to called_file.py (function_called()), and I want that function_called() method return flag or value if it's possible.
test_caller.py :
import sys
import subprocess
import os
def main():
#method can't return something
# my_path = os.path.join(os.path.abspath(__file__+"/../"),"test.py")
# script_descriptor = open(my_path)
# a_script = script_descriptor.read()
# sys.argv = [my_path, "variable1","https://google.com"]
# exec(a_script)
my_path = os.path.join(os.path.abspath(__file__+"/../"),"test.py")
#call function tes.py, but need a main method and so doesn't return the function value yet
test = subprocess.run(['python',my_path,"variable1","https://google.com"],check=True)
print(test)
if __name__ == '__main__':
main()
called_file.py :
import sys
import requests
def function_called(variable,variable2):
#Potato = Flag
try :
potato = 0
print(str(variable + " is ready to use "+ variable2 + " as variable number 2"))
request = requests.get(variable2)
if(request.status_code == 200):
response = request.text
return response
else :
potato = 1
#Flag exception potato = 1 => failure
except Exception as exc :
print("An error occured " + str(exc))
potato = 1
return potato
#I want that main issue disappear, for returning potato method value (flag 0 or 1) to my method's calling
# if __name__ == "__main__":
# function_called(sys.argv[1],sys.argv[2])
How could I do that ? Thanks for helping me.
Hello AKX thanks for your help, this solution might be good for our program,
For those who's had a similar problem, the solution now is this:
on test_caller.py :
def main():
test = importlib.import_module("called_file")
object = test.function_called("tata","https://www.google.com")
print(object) #do what you want from the returned object
Related
The variable SCRIPT_ENV gets set correctly in main block but that value does not propagate to other functions.
Here's my full working code:
import argparse
import settings
from multiprocessing import Pool
def set_brokers_and_cert_path():
brokers = None
cert_full_path = None
print("I am here man\n\n {0}".format(settings.SCRIPT_ENV))
if settings.SCRIPT_ENV == "some value":
brokers = # use these brokers
cert_full_path = settings.BASE_CERT_PATH + "test_env/"
if settings.SCRIPT_ENV == "some other value":
brokers = # use those brokers
cert_full_path = settings.BASE_CERT_PATH + "new_env/"
return brokers, cert_full_path
def func_b(partition):
kafka_brokers, cert_full_path = set_brokers_and_cert_path()
producer = KafkaProducer(bootstrap_servers=kafka_brokers,
security_protocol='SSL',
ssl_check_hostname=True,
ssl_cafile=cert_full_path +'cacert.pem',
ssl_certfile=cert_full_path + 'certificate.pem',
ssl_keyfile=cert_full_path + 'key.pem',
max_block_ms=1200000,
value_serializer=lambda v: json.dumps(v).encode('utf-8'),
key_serializer=str.encode
)
try:
producer.send(settings.KAFKA_TOPIC,
value="some val",
key="some key",
timestamp_ms=int(time.time()),
headers=[some headers],
partition=partition)
producer.flush()
except AssertionError as e:
print("Error in partition: {0}, {1}".format(partition, e))
def main():
with Pool(settings.NUM_PROCESSES) as p:
p.map(func_b, [i for i in range(0, 24)])
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--env", help="Environment against which the script needs to run")
args = parser.parse_args()
if args.env:
settings.SCRIPT_ENV = args.env
main()
else:
raise Exception("Please pass env argument. Ex: --env test/accept")
In the line "I am here man", it prints None as the value of SCRIPT_ENV.
Here, SCRIPT_ENV gets set perfectly in the if __name__ == "__main__" block, but in func_a, it comes as None.
contents of settings.py:
KAFKA_TOPIC = "some topic"
NUM_PROCESSES = 8
NUM_MESSAGES = 1000
SCRIPT_ENV = None
NUM_PARTITIONS = 24
TEST_BROKERS = [some brokers]
ACCEPT_BROKERS = [some brokers]
BASE_CERT_PATH = "base path"
I run it like this:
python <script.py> --env <value>
In your code example a few references are missing, without which it is not executable. First, we should find out the program parts that lead to the behavior you describe.
I do not suppose the argparse to be crucial. Basically you change an attribute in the module instance settings and call main(), so you can reduce the last part of the program to a few lines:
settings.SCRIPT_ENV = "test"
main()
Function main() propagates function func_b() over multiple processes. Function func_b() itself performs following steps:
Call of function set_brokers_and_cert_path() (you earlier named func_a())
Create an instance of KafkaProducer (producer)
Send some data per producer.
I cannot see that the created instance has any effect on the content of settings.SCRIPT_ENV, so I reduce function func_b() as well and leave only the first function call (for simplicity I take the original name func_a()).
Function func_a() (aka set_brokers_and_cert_path()) likewise has no apparent influence on settings.SCRIPT_ENV, since only a few strings are generated.
For debugging purposes I left the output of the text variables in the function.
All together, I come up with the following executable minimal example, which does not recreate for me the problem you describe (see output).
You can take this example and transfer it piece by piece back to your code and then see which part of the program leads to the problems.
import settings
from multiprocessing import Pool
def func_a():
print("I am here man\n{0}\n".format(settings.SCRIPT_ENV))
def func_b(partition):
func_a()
def main():
with Pool(settings.NUM_PROCESSES) as p:
p.map(func_b, [i for i in range(0, 24)])
settings.SCRIPT_ENV = "Test"
main()
Output
I am here man
Test
I am here man
Test
I am here man
Test
I am here man
Test
...
#RajatBhardwaj, at this point, it is up to you to decide whether you want to participate in finding a solution.
All others who are not interested in a solution would do well not to criticize solutions without having understood its intention.
This question already has answers here:
Why is Python running my module when I import it, and how do I stop it?
(12 answers)
Closed 3 years ago.
I am new to python programming. I have written sample code as flows.
temp.py
p = 'Tushar'
print(p)
class Basics:
def __init__(self, name, phNum):
self.name = name
self.phNum = phNum
def getString(self):
temp = self.name+' '+str(self.phNum)
print(type(temp))
return temp
bs = Basics("tushar", 9620207652)
x = bs.getString()
print(x)
def isBlue(isBlue):
if(isBlue):
print('Boolean true')
x = 'true'
else:
print('Boolean false')
x = 'false'
return x
tus = isBlue(True)
if(tus != None):
str = bs.getString().split(' ',1)
print(str[0])
print(str[1])
Hello.py
from temp import Basics
class Check:
def __init__(self):
print('Check obj')
def createName(self, firstName, lastName):
str = firstName + ' ' + lastName
return str
emp = Check()
completeName = emp.createName('Tushar', 'Banne')
print(completeName)
b = Basics('Tushar', 98765432)
val = b.getString
print("Val is {}".format(val))
I am running Hello.py file and getting the below output.
Tushar
class 'str'
tushar 9620207652
Boolean true
class 'str'
tushar 9620207652
Check obj
Tushar Banne
Val is (bound method Basics.getString of 0x0000024ECCCB5B70
The questions that I have are as follows
Why is the entire temp.py getting executed?
How to execute only getString method.
Why is it that when I use parenthesis after getString, it fails.
Why is the val printing object reference?
Am I following the correct standards of python coding?
Why is the entire temp.py getting executed?
That's how it works. Importing a module means essentially executing it.
How to execute only getString method.
In order to do so, the code in temp.py has to be changed in a way that it is only executed when the module is run at highest level ("as the __main__ module") instead of imported.
You do that this way:
if __name__ == '__main__':
p = 'Tushar'
print(p)
class Basics:
def __init__(self, name, phNum):
self.name = name
self.phNum = phNum
def getString(self):
temp = self.name+' '+str(self.phNum)
print(type(temp))
return temp
if __name__ == '__main__':
bs = Basics("tushar", 9620207652)
x = bs.getString()
print(x)
def isBlue(isBlue):
if(isBlue):
print('Boolean true')
x = 'true'
else:
print('Boolean false')
x = 'false'
return x
if __name__ == '__main__':
tus = isBlue(True)
if(tus != None):
str = bs.getString().split(' ',1)
print(str[0])
print(str[1])
Why is it that when I use parenthesis after getString, it fails.
I don't see it fail in your question.
Why is the val printing object reference?
Because you asked it to. Referring to a method or function means seeing it as an object and printing its string representation. If you call it (with the () behind), you perform a function call.
First, check this out What does if __name__ == "__main__": do?
When you are importing a python file, all of the code is executed.
What do you mean fails, what is the error?
val = b.getString means that now val references the method getString, that's why it is printed.
No, read the link above, also, python uses snake_case, not camelCase, so call the method get_string, not getString. (this obviously doesn't changes thte
Is there any way in Python2.7, we can capture and log the assert statements in general python scripting despite of assert is True or False
Suppose I assert following line in code:
assert len(lst) ==4
So is any way can log what statement is passed, at what line and it is true or false. I do not want to use a wrapper function, looking for something inbuilt in python .
Note: What I want to achieve is , suppose I have legacy code having 1000's of assert statements , without changing the code, I should be able to log which assert statement is executed and what is the output, Is its achievable in python 2.7.
try:
assert len(lst) == 4
print "True"
except AssertionError as e:
print "False"
Yes, you can define a custom excepthook to log some extra information:
import sys
import logging
def excepthook(*args):
logging.getLogger().error('Uncaught exception:', exc_info=args)
sys.excepthook = excepthook
assert 1==2
EDIT: Whoops I forgot you wanted to log even if it's true :) oh well I'll leave this for a little bit in case it informs you or someone else...
This is what I could achieve closet, as does not seem it is possible in Python2.7 . I created a wrapper function.
import inspect
def assertit(condition,message):
# The caller method
(frame, filename, line_number,function_name, lines, index) = inspect.getouterframes(inspect.currentframe())[1]
detailed_message=" => {message} [ {filename} : {line_number}]".format(message=message,line_number=line_number,
filename=filename)
if condition:
print "True %s"%detailed_message
return
raise AssertionError("False: %s"%detailed_message)
assertit(1==1,"Check if 1 equal 1")
assertit(1==2,"Check if 1 equal 2")
### HERE IS THE OUTPUT
True => Check if 1 equal 1 [ test_cases.py : 20]
Traceback (most recent call last):
File "test_cases.py", line 21, in <module>
assertit(1==2,"Check if 1 equal 2")
File "test_cases.py", line 19, in assertit
raise AssertionError("False: %s"%detailed_message)
AssertionError: False: => Check if 1 equal 2 [ test_cases.py : 21]
This is a proof of concept. So please downvote, or I will delete it...
The idea is to replace the assert statement with print statement at the execution.
import ast
import inspect
from your_module import main
def my_assert(test_result, msg):
assert test_result, msg
# if test_result is True, just print the msg
return "assert: {}, {}".format(test_result, msg)
class Transformer(ast.NodeTransformer):
def visit_Assert(self, node):
f = ast.Name(id='my_assert', ctx=ast.Load())
c = ast.Call(func=f, args=[node.test, node.msg], keywords=[])
p = ast.Print(values=[c], nl=True)
# set line#, column offset same as the original assert statement
f.lineno = c.lineno = p.lineno = node.lineno
f.col_offset =c.col_offset = p.col_offset = node.col_offset
return p
def replace_assert_with_print(func):
source = inspect.getsource(func)
ast_tree = ast.parse(source)
Transformer().visit(ast_tree)
return compile(ast_tree, filename="<ast>", mode="exec")
if __name__ == '__main__':
exec(replace_assert_with_print(main))
main(4)
And here is your_module.py
def main(x):
assert x == 4, "hey {} is not 4".format(x)
return x
I want raw input given in one file to be used in another file.
For this I defined all variables in a global_dec.py file . Then modified the value of these variables in main_file.py and when I got printed these variables in another file partfile.py then variables having integer and string value got modified but the raw input is not giving value given in main_fily.py
Code is as follow:
global_dec.py:
class common(object):
a=0
x="x inside global class "
y=raw_input(" enter input for the global class: ")
main_file.py:
from global_dec import common
common.x = " x changed inside main file "
common.a=1
def dummy():
print "dummy"
def main():
print " main"
if __name__ == '__main__':
main()
partfile.py:
from global_dec import common
def main():
print "x: "+common.x, " y: "+common.y, " a: "+str(common.a)
if __name__ == '__main__':
main()
If I am interpreting your question right you want to be able to do the following...
$ python main_file.py
enter input for the global class: something
main
$ python partfile.py
enter input for the global class: something else
x: x inside global class y: something else a: 0
If that is the case it is not possible because the python process ends and all values that are stored in memory for the app are thrown away. Change your main function in main_file.py to be exactly like the one in partfile.py and you will see that even the x and a values may change but they do not persist. The only way to have persistent data between running python processes is to use a database.
Probably a better way of showing this would be for your main_file.py to look like so...
from global_dec import common
common.x = 'i have changed'
common.a += 1
def main():
print "x: " + common.x + " a: " + str(common.a) + " y: " + common.y
Then run it twice and it should look like this.
$ python main_file.py
enter input for the global class: blah
x: I have changed a: 1 y: blah
$ python main_file.py
enter input for the global class: blah
x: I have changed a: 1 y: blah
Notice a will always be 1 since when it is imported at the beginning of the process it is 0 then is incremented to 1 and when the process finishes the variable is dumped from memory. I hope that helps
I'm current writing a short bit of code that will compare an etag for a web server page in a saved document to the etag on the server. If they are different, the code will indicate this. My code is below:-
import httplib
def currentTag():
f = open('C:/Users/ME/Desktop/document.txt')
e = f.readline()
newTag(e)
def newTag(old_etag):
c = httplib.HTTPConnection('standards.ieee.org')
c.request('HEAD', '/develop/regauth/oui/oui.txt')
r = c.getresponse()
current_etag = r.getheader('etag').replace('"', '')
compareTag(old_etag, current_etag)
def compareTag(old_etag, current_etag):
if old_etag == current_etag:
print "the same"
else:
print "different"
if __name__ == '__main__':
currentTag()
Now, reviewing my code, there is actually no reason to pass 'etag' from the currentTag() method to the newTag() method given that the pre-existing etag is not processed in newTag(). Nonetheless, if I don't do this, how can I pass two different values to compareTag(). So for example, when defining compareTag(), how can I pass 'etag' from the currentTag() method and 'current_etag' from the newTag() method?
you shouldn't chain your function calls like that, have a main block of code that calls the functions serially, like so:
if __name__ == '__main__':
currtag = currentTag()
newtag = newTag()
compareTag(currtag,newtag)
adjust your functions to return the relevant data
the basic idea of a function is that it returns data, you usually use functions to do some processing and return a value and not for control flow.
change your main to:
if __name__ == '__main__':
compareTag(currentTag(), newTag())
and then have currentTag() return e and newTag() return current_etag
def checkTags():
c = httplib.HTTPConnection('standards.ieee.org')
c.request('HEAD', '/develop/regauth/oui/oui.txt')
r = c.getresponse()
with open('C:/Users/ME/Desktop/document.txt', 'r') as f:
if f.readline() == r.getheader('etag').replace('"', ''): print "the same"
else: print "different"
you could make the variables (i.e. etag) global