I have script1, in there the String "path" gets set. Then the script1 runs blender as a subprocess, together with script2.
Now script2 needs to have access to the String "path", how can I do this?
Currently im Saving the string to a text file and then accesing it from script2 but I know this solution is very very ugly.
maybe someone has an idea ? :)
script1:
path=("/example/ex/")
subprocess.run([blenderpath, "--background", blenderscene, "--python", scriptpath])
script2 (atm just reading out the txt file with the right path, but that's not how I want it to be):
file=open("Blabla")
file_name = fiel.readline()
mat_path = file_name
def prepscene(mat_path)
It works right now with the text file, but If I try to import the variable into the second script it won't work, if I try to somehow start the blender script with it it also won't work.
import sys # to get command line args
argv = sys.argv
argv will be array
If you just want to access the varible you can use importing.
ScriptA:
...
path = "/example/ex/"
...
ScriptB:
from .ScriptA import path
(this only works if both scripts are in the same directory)
Related
I just started coding in python3 and for a school project we had to write a .txt file with the matrix in it and a .py file in which i am supposed to import the .txt file and execute the code. Everything should be executed in cmd with the following syntax: python matrix_input.txt matrixReloaded.py.
But i execute the code in cmd i get the following error: can't find 'main' module.
The .txt file i a simple text file with just the matrix in it.
In my .py file I had to create a directory for both the .txt file and the .py file and then follows the code that executes certain stuff on the matrix.
I tried multiple stuff but since I'm new to this nothing worked.
How do i fix this?
In order for a python script to execute it needs to have an entry point defined. That entry point is the main module. You are getting the error because it's not defined in your script. So, in your script, matrixReloaded.py, you want to include this module like this:
if __name__ == "__main__":
do_something()
Now, in order to execute the script from shell, you need to specify the script, and only then the arguments that you are trying to pass (in your case, a name of a file): python matrixReloaded.py matrix_input.txt
Lastly, to access the arguments (and then open the file or whatever you need to do with it), you will need to include the sys module. Here's an example:
import sys
if __name__ == "__main__":
print sys.argv[0] # prints matrixReloaded.py
print sys.argv[1] # prints matrix_input.txt
I have a script 'preprocessing.py' containing the function for text preprocessing:
def preprocess():
#...some code here
with open('stopwords.txt') as sw:
for line in sw.readlines():
stop_words.add(something)
#...some more code than doesn't matter
return stop_words
Now I want to use this function in another Python script.
So, I do the following:
import sys
sys.path.insert(0, '/path/to/first/script')
from preprocessing import preprocess
x = preprocess(my_text)
Finally, I end up with the issue:
IOError: [Errno 2] No such file or directory: 'stopwords.txt'
The problem is surely that the 'stopwords.txt' file is located next to the first script, not the second.
Is there any way to specify the path to this file, not making any changes to the script 'preprocessing.py'?
Thank you.
Since you're running on a *nix like system, it seems, why not use that marvellous environment to glue your stuff together?
cat stopwords.txt | python preprocess.py | python process.py
Of course, your scripts should just use the standard input, and produce just standard output. See! Remove code and get functionality for free!
The simplest, and possibly most sensible way is to pass in the fully pathed filename:
def preprocess(filename):
#...some code here
with open(filename) as sw:
for line in sw.readlines():
stop_words.add(something)
#...some more code than doesn't matter
return stop_words
Then you can call it appropriately.
Looks like you can put
import os
os.chdir('path/to/first/script')
in your second script. Please try.
import os
def preprocess():
#...some code here
# get path in same dir
path = os.path.splitext(__file__)
# join them with file name
file_id = os.path.join(path, "stopwords.txt")
with open(file_id) as sw:
for line in sw.readlines():
stop_words.add(something)
#...some more code than doesn't matter
return stop_words
I am working on project euler and wanted to time all of my code. What I have is directory of files in the form 'problemxxx.py' where xxx is the problem number. Each of these files has a main() function that returns the answer. So I have created a file called run.py, located in the same directory as the problem files. I am able to get the name of the file through command prompt. But when I try to import the problem file, I continue to get ImportError: No module named problem. Below is the code for run.py so far, along with the command prompt used.
# run.py
import sys
problem = sys.argv[1]
import problem # I have also tired 'from problem import main' w/ same result
# will add timeit functions later, but trying to get this to run first
problem.main()
The command prompts that I have tried are the following: (both of which give the ImportError stated above)
python run.py problem001
python run.py problem001.py
How can I import the function main() from the file problem001.py? Does importing not work with the file name stored as a variable? Is there a better solution than trying to get the file name through command prompt? Let me know if I need to add more information, and thank you for any help!
You can do this by using the __import__() function.
# run.py
import sys
problem = __import__(sys.argv[1], fromlist=["main"]) # I have also tired 'from problem import main' w/ same result
problem.main()
Then if you have problem001.py like this:
def main():
print "In sub_main"
Calling python run.py problem001 prints:
In sub_main
A cleaner way to do this (instead of the __import__ way) is to use the importlib module. Your run.py needs to changes:
import importlib
problem = importlib.import_module(sys.argv[1])
Alternatives are mentioned in this question.
For sure! You can use __ import_ built-in function like __import__(problem). However this is not recommended to use, because it is not nice in terms of coding-style. I think if you are using this for testing purposes then you should use unittest module, either way try to avoid these constructions.
Regards
You can use exec() trick:
import sys
problem = sys.argv[1]
exec('import %s' % problem)
exec('%s.main()' % problem)
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I'm current working through Learning Python the Hard Way, and it is perhaps going a little fast for me. I've input the following code, with along with the corresponding file. In the py file, I wrote:
#!/usr/bin/python
from sys import argv
script, filename = argv
txt = open(filename)
print "Here's your file %r:" % filename
print txt.read()
print "Type the filename again:"
file_again = raw_input("> ")
txt_again = open(file_again)
print txt_again.read()
And to run it, I wrote: python script.py readme.txt which ran the code.
However, I don't quite understand the process here:
How come #!/usr/bin/python must be at the top of the file
What is sys import argv
What is script, filename = argv
Is .read() a built in function?
#!/usr/bin/python is the so-called Shebang, a hint to the OS kernel that it is a Python script which should be executed with the given Python binary. Thus, if you chmod +x the script, you can even call it with ./script.py readme.txt.
from sys import argv is a command to import argv from the sys module directly into our namespace. So we can use argv to access it instead of sys.argv. If we only use it once, it may be better to just import sys and access everything inside via e.g. sys.argv. You'll find about that in the Python docs and/or tutorial.
script, filename = argv is a shorthand for
script = argv[0]
filename = argv[1]
as long as argv contains exactly 2 elements. You'll find about that in the Python docs and/or tutorial.
file.read() is indeed built-in, but as a file object method, not as a function as such.
The #!/usr/bin/python will turn your python script into an executable, a special unix trick. The executable scripts usually start with a line that begins with thecharacters #! (“hash bang”), followed by the path to the Python interpreter on your machine. Then by changing the mode to +x of that particular script file, you will be able to execute it on the prompt by just calling the name. As this path may be different for different machines, you can use the unix "env" workaround:
#!/usr/bin/env python
This will allow the env program to locate the python interpreter and execute the code
From modulename import something is used to import a module, but we are only importing "argv" attribute from the module sys. From is just like import, but does a bit more work for you where it copies the module's attribute (argv) in this case, so that they become simple variables in the recipient script.
script, filename = argv will simply assign argv[0] and argv[1] to script and filename respectively.
And finally, file.read is a builtin method for file objects.
Answers:
1) #!/usr/bin/python is there for UNIX users, it shows python where to find certain files. (Why do people write #!/usr/bin/env python on the first line of a Python script?)
2) sys import argv is the file in the argument [readme.txt] (http://www.tutorialspoint.com/python/python_command_line_arguments.htm)
3) script, filename = argv Script and Filename [new variables] take on the value from argv.
4) Yes, .read() is a built in function. (http://www.diveintopython.net/file_handling/file_objects.html)
Google is your friend on this one...
1) Unix-like convention. It allows to determine what to do with the file as soon as the first line of file is read.
2) from sys import argv means import only argv from the module named sys
3) a,b = 1,2 assigns 1 to a, and 2 to b. If there is an _iterable_ object on the RHS then such constructs are equivalent:
script, filename = argv
===
script = argv[0]
filename = argv[1]
4) Yes. Maybe not built-in strictly speaking - it's just a function provided in one of Python's standard input output module.
Is there a universal approach in Python, to find out the path to the file that is currently executing?
Failing approaches
path = os.path.abspath(os.path.dirname(sys.argv[0]))
This does not work if you are running from another Python script in another directory, for example by using execfile in 2.x.
path = os.path.abspath(os.path.dirname(__file__))
I found that this doesn't work in the following cases:
py2exe doesn't have a __file__ attribute, although there is a workaround
When the code is run from IDLE using execute(), in which case there is no __file__ attribute
On Mac OS X v10.6 (Snow Leopard), I get NameError: global name '__file__' is not defined
Test case
Directory tree
C:.
| a.py
\---subdir
b.py
Content of a.py
#! /usr/bin/env python
import os, sys
print "a.py: sys.argv[0]=", sys.argv[0]
print "a.py: __file__=", __file__
print "a.py: os.getcwd()=", os.getcwd()
print
execfile("subdir/b.py")
Content of subdir/b.py
#! /usr/bin/env python
import os, sys
print "b.py: sys.argv[0]=", sys.argv[0]
print "b.py: __file__=", __file__
print "b.py: os.getcwd()=", os.getcwd()
print
Output of python a.py (on Windows)
a.py: __file__= a.py
a.py: os.getcwd()= C:\zzz
b.py: sys.argv[0]= a.py
b.py: __file__= a.py
b.py: os.getcwd()= C:\zzz
Related (but these answers are incomplete)
Find path to currently running file
Path to current file depends on how I execute the program
How can I know the path of the running script in Python?
Change directory to the directory of a Python script
First, you need to import from inspect and os
from inspect import getsourcefile
from os.path import abspath
Next, wherever you want to find the source file from you just use
abspath(getsourcefile(lambda:0))
You can't directly determine the location of the main script being executed. After all, sometimes the script didn't come from a file at all. For example, it could come from the interactive interpreter or dynamically generated code stored only in memory.
However, you can reliably determine the location of a module, since modules are always loaded from a file. If you create a module with the following code and put it in the same directory as your main script, then the main script can import the module and use that to locate itself.
some_path/module_locator.py:
def we_are_frozen():
# All of the modules are built-in to the interpreter, e.g., by py2exe
return hasattr(sys, "frozen")
def module_path():
encoding = sys.getfilesystemencoding()
if we_are_frozen():
return os.path.dirname(unicode(sys.executable, encoding))
return os.path.dirname(unicode(__file__, encoding))
some_path/main.py:
import module_locator
my_path = module_locator.module_path()
If you have several main scripts in different directories, you may need more than one copy of module_locator.
Of course, if your main script is loaded by some other tool that doesn't let you import modules that are co-located with your script, then you're out of luck. In cases like that, the information you're after simply doesn't exist anywhere in your program. Your best bet would be to file a bug with the authors of the tool.
This solution is robust even in executables:
import inspect, os.path
filename = inspect.getframeinfo(inspect.currentframe()).filename
path = os.path.dirname(os.path.abspath(filename))
I was running into a similar problem, and I think this might solve the problem:
def module_path(local_function):
''' returns the module path without the use of __file__. Requires a function defined
locally in the module.
from http://stackoverflow.com/questions/729583/getting-file-path-of-imported-module'''
return os.path.abspath(inspect.getsourcefile(local_function))
It works for regular scripts and in IDLE. All I can say is try it out for others!
My typical usage:
from toolbox import module_path
def main():
pass # Do stuff
global __modpath__
__modpath__ = module_path(main)
Now I use _modpath_ instead of _file_.
You have simply called:
path = os.path.abspath(os.path.dirname(sys.argv[0]))
instead of:
path = os.path.dirname(os.path.abspath(sys.argv[0]))
abspath() gives you the absolute path of sys.argv[0] (the filename your code is in) and dirname() returns the directory path without the filename.
The short answer is that there is no guaranteed way to get the information you want, however there are heuristics that work almost always in practice. You might look at How do I find the location of the executable in C?. It discusses the problem from a C point of view, but the proposed solutions are easily transcribed into Python.
See my answer to the question Importing modules from parent folder for related information, including why my answer doesn't use the unreliable __file__ variable. This simple solution should be cross-compatible with different operating systems as the modules os and inspect come as part of Python.
First, you need to import parts of the inspect and os modules.
from inspect import getsourcefile
from os.path import abspath
Next, use the following line anywhere else it's needed in your Python code:
abspath(getsourcefile(lambda:0))
How it works:
From the built-in module os (description below), the abspath tool is imported.
OS routines for Mac, NT, or Posix depending on what system we're on.
Then getsourcefile (description below) is imported from the built-in module inspect.
Get useful information from live Python objects.
abspath(path) returns the absolute/full version of a file path
getsourcefile(lambda:0) somehow gets the internal source file of the lambda function object, so returns '<pyshell#nn>' in the Python shell or returns the file path of the Python code currently being executed.
Using abspath on the result of getsourcefile(lambda:0) should make sure that the file path generated is the full file path of the Python file.
This explained solution was originally based on code from the answer at How do I get the path of the current executed file in Python?.
This should do the trick in a cross-platform way (so long as you're not using the interpreter or something):
import os, sys
non_symbolic=os.path.realpath(sys.argv[0])
program_filepath=os.path.join(sys.path[0], os.path.basename(non_symbolic))
sys.path[0] is the directory that your calling script is in (the first place it looks for modules to be used by that script). We can take the name of the file itself off the end of sys.argv[0] (which is what I did with os.path.basename). os.path.join just sticks them together in a cross-platform way. os.path.realpath just makes sure if we get any symbolic links with different names than the script itself that we still get the real name of the script.
I don't have a Mac; so, I haven't tested this on one. Please let me know if it works, as it seems it should. I tested this in Linux (Xubuntu) with Python 3.4. Note that many solutions for this problem don't work on Macs (since I've heard that __file__ is not present on Macs).
Note that if your script is a symbolic link, it will give you the path of the file it links to (and not the path of the symbolic link).
You can use Path from the pathlib module:
from pathlib import Path
# ...
Path(__file__)
You can use call to parent to go further in the path:
Path(__file__).parent
Simply add the following:
from sys import *
path_to_current_file = sys.argv[0]
print(path_to_current_file)
Or:
from sys import *
print(sys.argv[0])
If the code is coming from a file, you can get its full name
sys._getframe().f_code.co_filename
You can also retrieve the function name as f_code.co_name
The main idea is, somebody will run your python code, but you need to get the folder nearest the python file.
My solution is:
import os
print(os.path.dirname(os.path.abspath(__file__)))
With
os.path.dirname(os.path.abspath(__file__))
You can use it with to save photos, output files, ...etc
import os
current_file_path=os.path.dirname(os.path.realpath('__file__'))