here is my Maya.env
λ cat C:\Users\roroco\Documents\maya\2018\Maya.env
MAYA_SCRIPT_PATH=C:/Users/roroco/OneDrive/maya/script
MAYA_PLUGIN_IN_PATH=C:/Users/roroco/OneDrive/maya/plugin
I'm sure my script exist:
λ cat C:\Users\roroco\OneDrive\maya\script\ro.py
def init():
print("prpr")
and in maya script editor, my script dir exist in MAYA_PATH_DIR
getenv MAYA_SCRIPT_PATH;
// Result: C:/Users/roroco/Documents/maya/projects/default/scripts;C:/Users/roroco/OneDrive/maya/script;C:/Users/roroco/Documents/maya/2018/scripts;C:/Users/roroco/Documents/maya/scripts;C:/Users/roroco/Documents/maya/2018/presets;C:/Users/roroco/Documents/maya/2018/prefs/shelves;C:/Users/roroco/Documents/maya/2018/prefs/markingMenus...
but when I import ro in script editor, it raise:
# Error: ImportError: file <maya console> line 1: No module named ro #
I hope I can write my maya script and auto sync to onedrive, how should i do
I don't understand maya doc say i can set MAYA_SCRIPT_PATH why it doesn't work
My tmp solution is add my script_dir in maya startup script
in C:\Users\roroco\Documents\maya\scripts\userSetup.py, add following code:
import imp
import os
imp.load_source("", "c:/users/" + os.environ["USERNAME"] + "/OneDrive/maya/script/userSetup.py")
and in my_script_dir/userSetup.py add my_script_dir to sys.path
import sys
import os
ro_script = os.path.dirname(__file__)
if ro_script not in sys.path:
sys.path.insert(0, ro_script)
you should be able to add python paths to your running maya dynamically with sys.path.insert or sys.path.append. You should not need to do anything more elaborate than that; you script should be importable if it's on the sys path.
For what you're trying to do a very common and clean solution is to use maya modules. Modules will allow you to append to the usual search directories, and they support network shares -- so you would add a module (in your maya modules path) and point its scripts directory to your onedrive. Modules can have their own userSetup.pys as well, which is very nice for keeping a clean separation between your code and anything else running on a particular machine.
More on modules here and here. The docs are here
You shouldn't have to add your path dynamically through userSetup.py.
Make sure you include PYTHONPATH in your Maya.env:
PYTHONPATH=C:\Users\roroco\OneDrive\maya\script
Checking my Windows home setup, I'm using back slashes in Maya.env, so you can see if switching helps. Instead of checking MAYA_PATH_DIR, check your sys.path to see if your directory is there. All Python modules need to be in one of these directories to import it:
import sys
for p in sys.path:
print p
You can also copy and paste your path to os.path.exists to confirm it really does exist. Sometimes it's the right path but the slashes make it so it doesn't resolve properly.
Related
I'm trying to import from a parent folder. The folder structure is (ignore the names)
experiments
__init__.py
poppy.py
ostepop
__ init__.py
importio.py
nopop
__ init__.py
loggio.py
I tried adding __init__.pyto every folder, but it didn't have any affect
import experiments.ostepop.loggiogives error message:
ModuleNotFoundError: No module named 'experiments'
and from ..experiments import poppy gives
ImportError: attempted relative import with no known parent package
Any tips on how to import poppy.py or loggio.py from importio.py?
import os
import sys
# Append parent directory to import path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
After this you can import your modules as if they were at, or under, the same directory as your source file. So from importio.py you can
import poppy # noqa
import nopop.logio # noqa
The # noqa is there to suppress "PEP 8: E402 module level import not at top of file" warning.
The __init__.py files are unnecessary for this solution, but you may want to keep them (except the top level one), if you plan to convert your subdirectories to modules one day.
If you want to understand how this solution work, please run
print(__file__)
print(os.path.abspath(__file__))
print(os.path.dirname(os.path.abspath(__file__)))
print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
It will print:
The current file name
The current file name, with absolute path
The current directory, with absolute path
And the parent directory, with absolute path
And sys.path.insert(0, ...) inserts this path to the beginning of the search path.
They are plenty of posts already, but it's still a tricky stuff to me as well.
So, though I'm still not sure what's the best practice, anyway here is how I handled this problem.
In the module where you want to do the imports, add
import sys
import os
sys.path.append(os.path.join(sys.path[0], '..'))
sys.path[0] is the absolute path to the module without the file name. It works both when the module is and is not the top-level script. If you don't know what is top-level script and how is it related to import mechanism, read this.
os.path.join is used to probably handle system difference. Anyway, os.path.join(sys.path[0], '..') will point to the parent path.
sys.path.append add that parent path to the searching space.
So, in your case, add previous code to importio.py, then you can do
from nopop import loggio
import poppy
in importio.py as well.
__init__.py is not used at all in this solution. You can delete them.
But I've seen many repos using __init__.py. So the best practice might involve using them.
If I understand you correctly, you want to import poppy.py from importio.py and debug with file model. Under this model, Python interpreter will not think of it as a package, so this code (import experiments.ostepop.loggio and from ..experiments import poppy) is invalid.
To solve this problem, you can debug this script with package model, which means run python -m experiments in terminal. It may be run correctly.
Having a strange error here. I had a previous directory structured as follows
main.py
foldername
modulename.py
now in main.py I called modulename.py by using import modulename.py as mn
now I am making changes but I still want to use the modules as before, so in a completely different location on my computer I have set up the structure as before:
newmain.py
foldername
modulename.py
to make sure I am working in the right directory I used:
import os
os.chdir('NewMainPath/')
which correctly sets the directory of the file but if I now use
import modulename.py as mn
it for some reason is linking to the previous modulename.py
That means if I make any changes it won't pick them up and is just linking to the previous location and I can't figure out why.
Instead of using os.chdir(newpath)
Try using
import sys
sys.path.insert(0, '/newpath')
import file
Also worth reading: Importing files from different folder in Python
A script at /foo/bar.py tries to run a second script /main.py using the subprocess module. Although main.py runs fine with python main.py in the Windows command prompt, running bar.py which calls main.py causes an error
ConfigParser.NoSectionError: No section: 'user'
Why is there now a problem with the path to settings.ini, and how can we fix it?
~/settings.ini
[user]
id: helloworld
~/foo/bar.py
subprocess.Popen([sys.executable, "../main.py"])
~/main.py
Config = ConfigParser.ConfigParser()
Config.read("settings.ini")
userId = Config.get('user', 'id')
If settings.ini is presumed to be in the same directory as main.py you can deduce its full path from __file__ and read the settings using the full path.
main.py:
import os
ini_path = os.path.join(os.path.dirname(__file__), "settings.ini")
Config = ConfigParser.ConfigParser()
Config.read(ini_path)
Check that the read() method returns a non-empty list otherwise it means that settings.ini is not found. Relative paths are resolved relative to the current working directory (place where you've run python), not script's directory (where bar.py is stored).
You should probably use appdirs.user_config_dir(), to get the directory where to put user's configuration files. Different OSes such as Windows, macOS, Linux distributions may use different defaults. appdirs follows conventions that are appropriate for a given OS.
If you want to get data stored in a file that is packaged with your installed Python modules then you could use pkgutil.get_data() or setuptools' pkg_resources.resource_string() that work even if your package is inside an archive. It is not recommended to construct the paths manually but if you need the directory with the current script then you could put get_script_dir() function into your script—it is more general than os.path.dirname(os.path.abspath(__file__)). If the relative position is always the same then you could use:
#!/usr/bin/env python
import os
import subprocess
import sys
main_script_dir = os.path.join(get_script_dir(), os.pardir)
subprocess.check_call([sys.executable, '-m', 'main'], cwd=main_script_dir)
See Python : How to access file from different directory
I created a test file called test.py (contained a class named test) and saved it into documents(Mac OS X 10.9.3)
I then attempted to use this file by writing from test import test. However, I got an error telling me that there was no module named test. Please can you shed some light into this issue.
The problem is that the Documents folder isn't usually in the PATH or PYTHONPATH, so the interpreter can't see scripts that are stored there (unless Documents happens to be the current working directory).
I can think of two solutions:
Move the file test.py to somewhere within Python's path.
You can find your PYTHONPATH with this script:
import os
try:
user_paths = os.environ['PYTHONPATH'].split(os.pathsep)
except KeyError:
user_paths = []
(From Mark Ransom’s answer to How do I find out my python path using python?)
You can find the system PATH with
import sys
print sys.path
Both of these return a list of folders. If you put test.py in one of those folders, then it will be seen by the interpreter.
For example, I usually install custom modules at
/Library/Python/2.7/site-packages
and then I can import them as normal.
Manually append Documents to your path.
You can use sys.path.append to add a directory to the path.
If you only need to use test.py in a handful of scripts, then you can add this code to each script you want to use test.py in:
import os
import sys
sys.path.append(os.path.join(os.environ['HOME'], 'Documents'))
from test import test
I have in my python workspace two Modules which need sip.pyd
Module1.pyd needs sip.pyd (which implements v 8.0-8.1)
Module2.pyd needs sip.pyd (another file, that implements v6.0)
So I can't just choose the newer one, it doesn't work: I have to keep them both!
(RuntimeError: the sip module implements API v6.0 but the fbx module requires API v8.1)
How can I import a module in .pyd extension (a python dll, not editable), and specify which sip.pyd to source?
As for a workaround, I manage to do that:
One sip.pyd is in my root site-packages location.
If I have to import the module that need the other sip.pyd, I remove root path form sys.path, and I append the precise folder path where the other sip.pyd are.
I can import my Module and restore previous sys.path.
Assuming you don't have a piece of code needing both files at once. I'd recommend the following:
install both files in 2 separate directories (call them e.g. sip-6.0 and sip-8.0), that you'll place in site-packages/
write a sip_helper.py file with code looking like
sip_helper.py contents:
import sys
import re
from os.path import join, dirname
def install_sip(version='6.0'):
assert version in ('6.0', '8.0'), "unsupported version"
keep = []
if 'sip' in sys.modules:
del sys.modules['sip']
for path in sys.path:
if not re.match('.*sip\d\.\d', path):
keep.append(path)
sys.path[:] = keep # remove other paths
sys.path.append(join(dirname(__file__), 'sip-%s' % version))
put sip_helper.py in site_packages (the parent directory of the sip-6.0 and sip-8.0 directories)
call sip_helper.install_sip at the startup of your programs
VirtualEnv is done to handle those case.
virtualenv is a tool to create isolated Python environments.
Using virtualenv, you will be able to create 2 environements, one with the sip.pyd in version 8.x another in version 6.0
I don't know if that works (if a module's name has to match its contents), but can't you just rename them to sip6.pyd resp. sip8.pyd and then do
if need6:
import sip6 as sip
else:
import sip8 as sip
?