How to automatically execute python script when Maya first loaded - python

I am trying to figure out how to use Python in Maya. I wanted to create a shelf in Maya and when I click that shelf, it will execute a file containing python code.
First thing, I figured out that we can't simply source python script. I followed this tutorial, so now I have a function psource(). In my shelf, I can just call psource("myPythonScript")
My problem is I have to somehow register psource() when Maya first loaded.
Any idea how to do this?

I suggest that you import the Python module with your button before calling the function. Assuming your script is in maya/scripts/tep.py, your button would do the following:
import tep
tep.psource()
If you wanted to modify the script and keep running the fresh version every time you hit the button, do this:
import tep
reload(tep)
tep.psource()
And if you want your module to load on Maya startup, create a file called userSetup.py in your maya/scripts directory and have it do this:
import tep
Then, your button can simply just:
tep.psource()
Or...
reload(tep)
tep.psource()

As part of the Maya startup sequence, it'll execute a file called userSetup.py for you. Within that file you can stick in standard python code to set up your environment, etc.
docs: http://download.autodesk.com/global/docs/maya2013/en_us/index.html?url=files/Python_Python_in_Maya.htm,topicNumber=d30e725143
That's the 2013 docco, but it's valid in 2011 and 2012 too. I expect it to be correct going back further as well, but I'm not running anything older here
For an example btw, my userSetup.py file looks like this:
import sys
# import a separate pyscript dir - we keep the standard scriptdir for MEL
sys.path.append(r'C:/Users/tanantish/Documents/maya/2012-x64/pyscripts')
# odds on i'm going to want PyMEL loaded by default
# and we are going to try distinguish it from the old maya.cmds
# since the two since they're similar, but not the same.
# from pymel.core import *
import pymel.core as pm
# and we might as well get maya.cmds in for testing..
import maya.cmds as mc
# import local toolpack
import tantools
(edited to caps out userSetup.py as per #jdi's comment)

Which version of Maya are you running? If later than 8.5, Maya has python built in. Any python scripts you put in your local Maya script directory gets automatically sourced. You can inside the script editor source and run python scripts.
To automatically run:
Create a userSetup.mel file in myDocs\maya\mayaVersion\scripts
Inside the userSetup, use this syntax to import and run scripts:
python("from package import module");
python("module.method(\"passedVar1\", \"passedVar2\")");
Hope that helps
P.S Same syntax applies for shelf buttons. Just have to make sure that you have your python path set for Maya so that your code can be found. The local script directory is already included.....

I like to use
exec(open('c:\whatever\whatever\scriptname.py'))
See if that works for you! :)

Related

How to make a file with python using nikkiepy

I've been stuck on C++ for a bit, so I decided to continue my python classes (In which I'm currently working with the Nikkiepy library) and I'm trying to figure out how to make a file. This is my current code:
import nikkiepy.files as npyf
npyf.mkfile("coakey", "./data", ".cde")
for some reason it keeps asking for a folder
You're using "Coakey" as the folder, you should instead do
import nikkiepy.files as npyf
npyf.mkfile(path="./", name="coakey", extension="cde")
Also, leave the "." out of the extension, because that gets added automatically

python get the script which imported my script

I want to make my own programming language based on python which will provide additional features that python wasn't provide, for example to make multiline anonymous function with custom syntax. I want my programming language is so simple to be used, just import my script, then I read the script file which is imported my script, then process it's code and stop anymore execution of the script which called my script to prevent error on syntax...
Let say there are 2 py file, main.py and MyLanguage.py
The main.py imported MyLanguage.py
Then how to get the main.py file from MyLanguage.py if main.py can be another name(Dynamic Name)?
Additional information:
I using python 3.4.4 on Windows 7
Like Colonder, I believe the project you have in mind is far more difficult than you imagine.
But, to get you started, here is how to get the main.py file from inside MyLanguage.py. If your importing module looks like this
# main.py
import MyLanguage
if __name__ == "__main__":
print("Hello world from main.py")
and the module it is importing looks like this, in Python 3:
#MyLanguage.py
import inspect
def caller_discoverer():
print('Importing file is', inspect.stack()[-1].filename)
caller_discoverer()
or (edit) like this, in Python 2:
#MyLanguage.py
import inspect
def caller_discoverer():
print 'Importing file is', inspect.stack()[-1][1]
caller_discoverer()
then the output you will get when you run main.py is
Importing file is E:/..blahblahblah../StackOverflow-3.6/48034902/main.py
Hello world from main.py
I believe this answers the question you asked, though I don't think it goes very far towards achieving what you want. The reason for my scepticism is simple: the import statement expects a file containing valid Python, and if you want to import a file with your own non-Python syntax, then you are going to have to do some very clever stuff with import hooks. Without that, your program will simply fail at the import statement with a syntax error.
Best of luck.

Python Calling Function from Another File

I am using Python 2.7 on Windows 7 Professional.
I am trying to call a function saved in another file to run in this file's code.
Function called dosomething is found in anotherfile.py
anotherfile.py is in the same directory as current code.
My call in this file is simple:
import anotherfile
print anotherfile.dosomething
I am getting an error: No module named anotherfile
The problem is the same as I found in this post
I don't understand the solution but I'd like any insight?
Thank you.
EDIT: The other question/answers discuss resetting CLASSPATH and setting PYTHONPATH. I explored this but was not sure how to do this. Perhaps relevant?
Let us have two files in the same directory. Files are called main.py and another.py.
First write a method in another.py:
def do_something():
return "This is the do something method"
Then call the method from main.py. Here is the main.py:
import another
print another.do_something()
Run main.py and you will get output like this:
This is the do something method
N.B.: The above code is being executed using Python 2.7 in Windows 10.
Specify the module then the file then the import like so:
from this_module.anotherfile import dosomething
or if you want all functions from "anotherfile.py"
from this_module.anotherfile import *
and then you can call the "dosomething" command without the "anotherfile" prefix.
I ran into same problem. After ample of trials, I ended up solving it with the below mentioned solution:
Make sure your current file and anotherfile.py lies in same location of system path.
Say your another.py and current file lies at location : "C:/Users/ABC"
In case, one is not aware of system path. Use below code in current file:
import sys
print(sys.path)
import sys
sys.path.append('/C:/Users/ABC/')
Then you do below code in same current code:
from another import dosomething
I found the issue. Python was looking in another directory for the files. I explicitly set my working directory as the path to where thisfile.py and anotherfile.py reside and it works. Thank you for all the quick replies.

How to write a Python package/module?

As I'm a novice, I started learning python by writing simple programs using python GUI .. everytime, when I try to clear the console I need to define the following few lines of code
import os
def cls():
os.system('cls')
print("Console Cleared")
and later I call it as
cls()
now I'm tired of writing the above code again and again(every time I open the gui window )..
so, I want to create a module called cls for future use to save my time ..
in the end I'll call it as follows
import cls
cls()
is there a way to do this ...
Thanks !
Well, a solution is to create a directory to add your modules and add this directory to the Python pat. For example, you can create a directory at, let us say, C:\mypymodules and put a cls.py file there with your function.
Now, let us add this directory to the Python path. Follow these instructions, just inserting C:\mypymodules in place of the directories mentioned there. Now, open a new command line window and try to import the module.
Another solution is to use distutils*. Instead of creating your own modules directory, in the same directory of your cls.py file create a file named setup.py with the following content:
from distutils.core import setup
setup(name='cls', py_modules=['cls'])
Then, just execute it:
> python setup.py install
This may install your module in the default Python library directories. Actually, this is the way (or, better yet, one of the ways) to pack, manage or python packages.
(I am not really using Windows, so some details may be broken. Nonetheless, I believe the general concepts are the same.)
* Some may argue about using setuptools but I think it is really overkill for your case. Anyway, if you want to learn more, see this question.
If you put your cls() function in a file called cls.py, and put that either in the same directory as the program that's calling it or else somewhere in your PYTHONPATH on your system, then you can use your function like this:
import cls
cls.cls()
This is because the cls() function is inside the cls module (the name of the module is determined by the file name).
If you want to just be able to do cls() then do this:
from cls import cls
cls()
You can spice it up a little bit by making your module cross platform. Here it is:
import os, sys
def cls():
if 'win' in sys.paltform:
os.system('cls')
print 'Console cleared'
else:
os.system('clear')
print 'Console cleared'
Now, you can use it in any other script using:
from cls import cls
cls()

python refresh/reload

This is a very basic question - but I haven't been able to find an answer by searching online.
I am using python to control ArcGIS, and I have a simple python script, that calls some pre-written code.
However, when I make a change to the pre-written code, it does not appear to result in any change. I import this module, and have tried refreshing it, but nothing happens.
I've even moved the file it calls to another location, and the script still works fine. One thing I did yesterday was I added the folder where all my python files are to the sys path (using sys.append('path') ), and I wonder if that made a difference.
Thanks in advance, and sorry for the sloppy terminology.
It's unclear what you mean with "refresh", but the normal behavior of Python is that you need to restart the software for it to take a new look on a Python module and reread it.
If your changes isn't taken care of even after restart, then this is due to one of two errors:
The timestamp on the pyc-file is incorrect and some time in the future.
You are actually editing the wrong file.
You can with reload re-read a file even without restarting the software with the reload() command. Note that any variable pointing to anything in the module will need to get reimported after the reload. Something like this:
import themodule
from themodule import AClass
reload(themodule)
from themodule import AClass
One way to do this is to call reload.
Example: Here is the contents of foo.py:
def bar():
return 1
In an interactive session, I can do:
>>> import foo
>>> foo.bar()
1
Then in another window, I can change foo.py to:
def bar():
return "Hello"
Back in the interactive session, calling foo.bar() still returns 1, until I do:
>>> reload(foo)
<module 'foo' from 'foo.py'>
>>> foo.bar()
'Hello'
Calling reload is one way to ensure that your module is up-to-date even if the file on disk has changed. It's not necessarily the most efficient (you might be better off checking the last modification time on the file or using something like pyinotify before you reload), but it's certainly quick to implement.
One reason that Python doesn't read from the source module every time is that loading a module is (relatively) expensive -- what if you had a 300kb module and you were just using a single constant from the file? Python loads a module once and keeps it in memory, until you reload it.
If you are running in an IPython shell, then there are some magic commands that exist.
The IPython docs cover this feature called the autoreload extension.
Originally, I found this solution from Jonathan March's blog posting on this very subject (see point 3 from that link).
Basically all you have to do is the following, and changes you make are reflected automatically after you save:
In [1]: %load_ext autoreload
In [2]: %autoreload 2
In [3]: Import MODULE
In [4]: my_class = Module.class()
my_class.printham()
Out[4]: ham
In [5]: #make changes to printham and save
In [6]: my_class.printham()
Out[6]: hamlet
I used the following when importing all objects from within a module to ensure web2py was using my current code:
import buttons
import table
reload(buttons)
reload(table)
from buttons import *
from table import *
I'm not really sure that is what you mean, so don't hesitate to correct me. You are importing a module - let's call it mymodule.py - in your program, but when you change its contents, you don't see the difference?
Python will not look for changes in mymodule.py each time it is used, it will load it a first time, compile it to bytecode and keep it internally. It will normally also save the compiled bytecode (mymodule.pyc). The next time you will start your program, it will check if mymodule.py is more recent than mymodule.pyc, and recompile it if necessary.
If you need to, you can reload the module explicitly:
import mymodule
[... some code ...]
if userAskedForRefresh:
reload(mymodule)
Of course, it is more complicated than that and you may have side-effects depending on what you do with your program regarding the other module, for example if variables depends on classes defined in mymodule.
Alternatively, you could use the execfile function (or exec(), eval(), compile())
I had the exact same issue creating a geoprocessing script for ArcGIS 10.2. I had a python toolbox script, a tool script and then a common script. I have a parameter for Dev/Test/Prod in the tool that would control which version of the code was run. Dev would run the code in the dev folder, test from test folder and prod from prod folder. Changes to the common dev script would not run when the tool was run from ArcCatalog. Closing ArcCatalog made no difference. Even though I selected Dev or Test it would always run from the prod folder.
Adding reload(myCommonModule) to the tool script resolved this issue.
The cases will be different for different versions of python.
Following shows an example of python 3.4 version or above:
hello import hello_world
#Calls hello_world function
hello_world()
HI !!
#Now changes are done and reload option is needed
import importlib
importlib.reload(hello)
hello_world()
How are you?
For earlier python versions like 2.x, use inbuilt reload function as stated above.
Better is to use ipython3 as it provides autoreload feature.

Categories

Resources