I am new to Stackoverflow so I will try to ask the question as detailed as possible. I am facing an issue where I call a function to write a value to a python file, and another function to return this written value. However, the function that supposed to return this written value does not return the most updated value after the write function.
I have done multiple researches and tried multiple methods from other questions posted in Stackoverflow but it still didn't work for me.
Here is what I currently have:
In test.py
import random
import string
from test_value import *
def write():
letters = string.ascii_letters
value_to_be_passed = ''.join(random.choice(letters) for i in range(10))
f = open("test_value.py", "w")
f.write('value="' + value_to_be_passed + '"')
f.close()
def read():
print(value)
write()
read()
In test_value.py
value="MutmHDlVQj"
If you run this file, it will generate a new string and store this new string into test_value.py. But when the function read() runs, it does not print out the newly generated string. It seem as though when I run this program, python will immediately store the value in test_value.py in it's memory and does not return the new value when called.
I have tried fsync, flush, with open but it still doesn't work. It won't be ideal to read the file as a plaintext as I might be storing multiple variables in test_value.py so that my program can call the value of the respective variables.
You can run the code in your ide, upon the first run it will print MutmHDlVQj in your terminal even though the goal is supposed to print the newly generated string.
Does anyone know how this could be solved? Thank you in advance.
Workaround Solution
Thanks to tripleee that gave me the idea of this cheap solution. However, I am sure there are better methods that can be done to solve this issue. May the experts give your opinions on this!
Instead of importing at compile time, I ran the importing when I really needed it.
def read():
from test_value import *
print(value)
The import happens when your script is compiled, before it runs and writes anything to the new file. If you want to import something during runtime, you can do that with importlib; but this seems fundamentally like an XY problem. If your task is to serialize some data, use pickle or simply save the data in a standard format like JSON.
from import method you can't pass a variable so simply for a return value, you must specify in test_value.py a return function.
here's the functioning code:
import random
import string
from test_value import value
def write():
letters = string.ascii_letters
value_to_be_passed = ''.join(random.choice(letters) for I in range(10))
f = open("test_value.py", "w")
f.write('value="' + value_to_be_passed + '"')
f.close()
def read():
returned_value = value()
print(returned_value)
write()
read()
in test_value.py:
def value():
value="SbjvLSYfNs"
return value
written like this I have a functioning code that prints the value returned from another python file like you asked.
hope it helps in the future, but remember that if you want to return a value, you must specify the return function
Related
When I run the below code my websites or steam still open. Shouldn't I need to state print(link) or print(steam) for them to open?
import os
import webbrowser
import subprocess
import random
urls = ['https://www.ft.com/',
'https://www.youtube.com/watch?v=xvqcFcfhUVQ',
'https://roadmap.sh/backend',
'https://www.youtube.com/watch?v=YYXdXT2l-Gg&list=PL-osiE80TeTskrapNbzXhwoFUiLCjGgY7']
foxpath = 'C:/Program Files/Mozilla Firefox/Firefox.exe %s'
link = webbrowser.get(foxpath).open(random.choice(urls))
steam = subprocess.call(['C:/Program Files (x86)/Steam/Steam.exe'])
Why does this happen?
I eventually want to run the program from a function call, like below.
def wildcard():
print(random.choice(link, steam))
wildcard()
No, there is nothing special about print. print is just a function that takes in some value and displays it to the user.
If you had instead steam = 3 * 4, would you be surprised to learn that the value 12 is computed, and steam becomes a name for that value, even if you don't do anything with it? It's the same thing here - calling subprocess.call causes the program to launch, and it has nothing to do with the name steam, nor anything that you do or don't do with that name subsequently.
If you were to add the print(steam) line that you have in mind, what it would display (after you close steam and control returns to your program) is the "return code" of that program - this gets into the details of how your operating system works, but most likely it would be something like 0.
If you want something that you can later call in order to launch Steam - well, that's a function. Like you already know how to do:
def steam():
subprocess.call(['C:/Program Files (x86)/Steam/Steam.exe'])
As soon as you issue webbrowser.get or subprocess.call, they execute. Your variables are really storing the return values of those functions, not aliases to those function calls.
If you want to alias the function calls as it appears you are intending, you could do something like this:
def open_link():
return webbrowser.get(foxpath).open(random.choice(urls))
def open_steam():
return subprocess.call(['C:/Program Files (x86)/Steam/Steam.exe'])
Then your top level would be:
def wildcard():
random.choice([link, steam])()
wildcard()
Note the syntax difference for choosing the functions randomly. See this answer for more clarification.
You do invoke something:
steam = subprocess.call(['C:/Program Files (x86)/Steam/Steam.exe'])
The documentation for subprocess.call is clear on what the call method does: it invokes the given argument as a subprocess.
The problem is that your code isn't inside a function, so, when you execute it, it runs all the diretives including
steam = subprocess.call(['C:/Program Files (x86)/Steam/Steam.exe'])
Which calls C:/Program Files (x86)/Steam/Steam.exe, opening your steam app.
Hope it helps.
Thank you, I understand now. I actually just resolved the problem with the following
def wildcard():
for x in range(1):
rand = random.randint(1, 10)
if rand > 5:
link = webbrowser.get(foxpath).open(random.choice(urls))
else:
subprocess.call(['C:/Program Files (x86)/Steam/Steam.exe'])
wildcard()
I want to do a subprocess.call to create a file (and eventually populate it). Here's my code:
#!/usr/bin/python
import sys
import subprocess
import psycopg2
import base64
import urlparse
sys.path.append('/var/www/cgi-bin')
def index(req):
out = ""
mkFile = str("touch /etc/httpd/conf/ipForward/90.conf")
subprocess.call([mkFile],shell=True)
return out
mkFile = str("touch /etc/httpd/conf/ipForward/111.conf")
subprocess.call([mkFile],shell=True)
Right now only the bottom command works, but these two subprocesses should do the same exact thing (I've named the file differently for testing purposes). I know there is a better way to do this but, for my own edification (and sanity) can someone explain the difference?
~~~~~~~~~~~~~~~~~~~~~~~EDIT COMPLETE CODE~~~~~~~~~~~~~~~~~~~~~
def index(req):
out = ""
conn = psycopg2.connect("dbname='pwp' host='localhost' user='~~~' password='~~~~~'")
c = conn.cursor()
inClCN = str(req.subprocess_env['SSL_CLIENT_S_DN_CN'])
c.execute("select * from Users where cn = '{0}';".format(inClCN))
rows = c.fetchall()
for row in rows:
port = row[0]
mkFile = str("touch /etc/httpd/conf/ipForward/{0}.conf".format(port))
subprocess.call([mkFile],shell=True)
insert = r"""Listen {0}\n\n<VirtualHost _default_:{1}>\n\nDocumentRoot '/var/www/html/'\nDirectoryIndex indexAlex.py\n\nRewriteEngine On\n\nErrorLog /etc/httpd/logs/error_log\nTransferLog /etc/httpd/logs/access_log\nLogLevel warn\n\n\nNSSVerifyClient require\n\nNSSEngine on\nNSSFIPS on\nNSSProtocol(MORE CONF STRING)</VirtualHost>""".format(port,port)
confFile = str('echo "{0}" >> /etc/httpd/conf/ipForward/{1}.conf'.format(insert,port))
subprocess.call([confFile],shell=True)
return out
The only reason I need the req is to get the environmental variable from apache. I don't really know how that works but I've been using that in other code without subprocesses.
Your first call to subprocess.call is within a def statement. A def statement doesn't actually call anything under it right away, instead it defines a function, which is a block of code you can reuse anywhere else.
The first "call" to subprocess.call doesn't do anything because you are just defining it as part of a reusable piece of code, but never actually using this reusable piece of code.
If you want to "use" the first call, you need to call the function you just defined using def:
Add the following to the end of your script:
index(None)
and the "first" call should happen, but after the first.
You can read more about how the def statement works and about functions here.
Using Python 3, I have a console application that I am porting to a GUI. The code has a bunch of print statements, something like this:
print(f1(), f2(), f3(), sep=getsep(), end=getend())
I would like to convert these calls into something like:
GuiPrintLine(f1(), f2(), f3(), sep=getsep(), end=getend())
where each line is eventually rendered using some (undefined) GUI framework.
This is easy to do if I can convert the arguments to print into to the string that print would normally produce without the side-effect of actually printing to sysout. In other words, I need a function like this:
s = print_to_string(*args, **kwargs)
How do I format a set of parameters to print(...) into a single string that produces the same output as print() would produce?
I realize I could emulate print by concatenating all the args with sep and ends, but I would prefer to use a built-in solution if there is one.
Using print and redirecting sysout is not attractive since it requires modifying the global state of the app and sysout might be used for other diagnostics at the same time.
It seems like this should be trivial in Python, so maybe I'm just missing something obvious.
Thanks for any help!
Found the answer via string io. With this I don't have to emulate Print's handling of sep/end or even check for existence.
import io
def print_to_string(*args, **kwargs):
output = io.StringIO()
print(*args, file=output, **kwargs)
contents = output.getvalue()
output.close()
return contents
My solution :
def print_to_string(*args, **kwargs):
newstr = ""
for a in args:
newstr+=str(a)+' '
return newstr
I am looking for a way to quickly print a variable name and value while rapidly developing/debugging a small Python script on a Unix command line/ssh session.
It seems like a very common requirement and it seems wasteful (on keystrokes and time/energy) to duplicate the variable_names on every line which prints or logs its value. i.e. rather than
print 'my_variable_name:', my_variable_name
I want to be able to do the following for str, int, list, dict:
log(my_variable_name)
log(i)
log(my_string)
log(my_list)
and get the following output:
my_variable_name:some string
i:10
my_string:a string of words
my_list:[1, 2, 3]
Ideally the output would also log the function name.
I have seen some solutions attempting to use locals, globals, frames etc., But I have not yet seen something that works for ints, strings, lists, and works inside functions too.
Thanks!
Sorry to Necro this ancient thread, but this was surprisingly difficult to find a good answer for.
Using the '=' sign after the variable achieves this. For instance:
import pathlib as pl
import logging
logging.basicConfig(level=logging.DEBUG)
data_root = pl.Path("D:\Code_Data_Dev\Data\CSV_Workspace_Data")
logging.debug(f'{data_root=}')
This outputs
DEBUG:root:data_root=WindowsPath('D:/Code_Data_Dev/Data/CSV_Workspace_Data')
If the tool you need is only for developing and debugging, there's a useful package called q.
It has been submitted to pypi, it can be installed with pip install q or easy_install q.
import q; q(foo)
# use #q to trace a function's arguments and return value
#q
def bar():
...
# to start an interactive console at any point in your code:
q.d()
The results are output to the file /tmp/q (or any customized paths) by default, so they won't be mixed with stdout and normal logs. You can check the output with tail -f /tmp/q. The output is highlighted with different colors.
The author introduced his library in a lightning talk of PyconUS 2013. The video is here, begins at 25:15.
Here is another evil hack:
import inspect
def log(a):
call_line = inspect.stack()[1][4][0].strip()
assert call_line.strip().startswith("log(")
call_line = call_line[len("log("):][:-1]
print "Log: %s = %s" % (call_line, a)
b=3
log(b)
This obviously would need some range checks, better parsing, etc.
Also works only if the calls is made always in the same way and has probably more - unknown to me - assumptions...
I don't know any way to simply get the name of a variable of a string.
you can however get the list of argument of the current fonction log.
import inspect
def log(a):
frame = inspect.currentframe()
args, _, _, values = inspect.getargvalues(frame)
print "%s:%s" % (args[0], values[args[0]])
I'm trying to import a class from another file and then implement the member function in my main function. I'm really just trying to understand the syntax of Python, as I am still really new to the language. My program is simple, and isn't really meant to do much. I'm more or less just trying to get a grasp on how Python goes about this. My class file is called Parser.py and here's is the code:
class Parser:
def hasMoreCommands(self):
if not c:
return false
else:
return true
and my main function is in a file called jacklex.py The main function only opens an input file and copies the text to an output file. Here's the code:
import Parser
from Parser import *
f = open('/Python27/JackLex.txt' , 'r+')
fout = open('/Python27/output.txt' , 'w')
while Parser.hasMoreCommands:
c = f.read(1)
fout.write(c)
print "All Done"
f.close()
fout.close()
My issue is that my program runs, but it seems to be getting stuck in an infinite loop. There's never any text printed to the ouput file, and "All Done" is never printed in the Python Shell. Am I missing something essential that's causing my program not to work properly?
Parser.hasMoreCommands refers to the (unbound) method, not the output. It'll always evaluate to True.
You need to create an instance of your parser and then call the method:
parser = Parser()
while parser.hasMoreCommands():
...