Using Python

There are a number of differences in how Maya commands are invoked in Python relative to how they are used in MEL, given that the languages are so different.

Here are the basics to getting started with Python in Maya:

Entering Python commands in Maya

There are several ways of entering Python in Maya.

Script Editor

To facilitate having both MEL and Python scripting at the same time in Maya, the Script editor has been modified to have separate tabs for each language. Statements entered into the MEL tabbed window are sent to MEL to be processed; similarly, statements entered into the Python tabbed window are processed by Python.

Returned results from Python come prefixed with the Python comment character (#).

You can enter commands directly in the tab, or you can load an existing .py file into the tab.

Note:

In the script editor, you can use auto-completion to help you find command names more quickly. For more information, see Get help on a MEL command.

For more information, see Script editor.

Command line and Shelf

You can also enter short Python commands into the command-line. A toggle allows you to enter either MEL or Python commands.

You can -drag Python scripts to the Shelf, just like MEL scripts.

Maya Python module

The Python bindings for all of the native Maya commands are in the maya.cmds module. In order to access these commands, you must enter the following in the Python tab of the Script editor in each session:

import maya.cmds

This allows you to use Maya commands. For example:

maya.cmds.ls()
maya.cmds.sphere( radius=4 )

You can import Maya commands to a different and shorter namespace:

import maya.cmds as cmd
cmd.sphere()
Tip: You can import maya.cmds automatically in the userSetup.py file. You can modify this to use your preferred prefix; for example:

import maya.cmds as mc mc.sphere()

Note: Alternatively, you can import the Maya commands into the top-level namespace using:

from maya.cmds import *

after which you can use a briefer way to reference Maya commands:

ls() sphere( radius=4 )

WARNING: Importing to the top-level namespace overrides definitions from Python built-in and other modules.

For example, Python has its own help system and a call to the Python version of help produces output that is specific to Python. A call to maya.cmds.help provides help about Maya commands. Importing maya.cmds into the top-level namespace would result in not being able to access Python help.

Flags (named arguments)

Flags are handled differently in Python than they are in MEL. MEL was designed with a shell command style syntax.

For Maya commands in Python, the command argument syntax has been adapted in a way that is natural for Python. As a result, flags—both long and short forms—are passed to commands as named arguments. The name of the argument is the flag name and the flag’s arguments are passed to the named argument.

Single arguments

The MEL sphere command is:

sphere -radius 4;

In the Python version, the flag radius is referenced as a named argument and, since there is a single argument, the value is passed as follows:

maya.cmds.sphere( radius=4 )

Multiple arguments

If the flag has multiple arguments, then the arguments need to be packed into a list or a tuple. Here is an example of a command with a flag that has three arguments.

# With a tuple maya.cmds.ambientLight( rgb=( 0.2, 0.3, 0.4 ) )
# With a list maya.cmds.ambientLight( rgb=[ 0.2, 0.3, 0.4 ] )

Required arguments (True/False)

Named arguments must have a value associated with them. However, not all Maya flags require a value (for example, ls -sl). In order to maintain a consistent syntax, the Autodesk Maya Python implementation requires you to assign a boolean argument to those flags that do not normally take any arguments. If the boolean value is False, then the flag is ignored; if it is True, the flag is used. For example:

# Pass selection flag maya.cmds.ls( selection=True )
# Selection flag is ignored here maya.cmds.ls( selection=False )

Multiple named arguments

Some flags may be used multiple times in one command call. For example, in MEL:

ls -type nurbsSurface -type transform;

In Python, you would use the named argument type and pass the values in a list or a tuple.

maya.cmds.ls( type=['nurbsSurface','transform'] )

In the case where a flag is used multiple times and has multiple arguments, the value is a list of lists. Tuples may be used instead of lists, so you may use a tuple of lists, a list of tuples, or a tuple of tuples. For example, the curveOnSurface command in MEL:

curveOnSurface -d 3 -uv 0 0 -uv 0.3 0.5 -uv 0.5 0.6 -uv 0.9 1.0 surface1;

In Python:

maya.cmds.curveOnSurface( 'surface1', d=3, uv=[(0,0),(0.3,0.5),(0.5,0.6),(0.9,1.0)] )

If you use more than one argument flag, Python returns an error (‘Duplicate keyword argument’).

Ranges

There are three types of ranges in Maya commands: time, index, and float. All ranges must be specified using tuples in Python. Any tuple may have either one or two values. A tuple with one value is specified as a value in brackets with a single comma; multiple single-valued tuples are specified using set notation.

As well, time ranges support units. To specify units, you must use strings. You can mix units as each value is parsed separately.

These are valid time ranges:

(1,) (1,10) ('1sec','10sec') ('1min:2min')

The following table uses the cutKey command as an example of specifying time and index ranges.

MEL range Meaning Python range

-time 10pal

Cut the key at frame 10 (PAL format)

time=('10pal',)

-time 1.0sec -time 15ntsc -time 20

Cut the keys at time 1.0 second, frame 15 (in NTSC format), and time 20 (in the currently-defined global time unit).

time=[('1.0sec',), ('15ntsc',), (20,)]

-time "10:20"

Cut all keys in the range from 10 to 20, inclusive, in the current time unit.

time=(10,20)

-time "10:"

Cut all keys from time 10 (in the current time unit) onwards.

time=('10:',)

-time ":10"

Cut all keys up to (and including) time 10 (in the current time unit).

time=(':10',)

-time ":"

Cut all keys

time=(':',)

-index 0

Cut the first key of each animation curve.

(Indices are 0-based.)

index=(0,)

-index 2 -index 5 -index 7

Cut the 3rd, 6th, and 8th keys.

index=[(2,),(5,),(7,)]

-index "1:5"

Cut the 2nd, 3rd, 4th, 5th, and 6th keys of each animation curve.

index=[("1:5",)]

Changes to certain command flags

Certain flag changes to Maya commands are necessary because the arguments for multi-use flags in Python must be passed as a list to the flag. This causes a problem for commands in which different multi-use flags must be mixed-and-matched. Since each multi-use flag’s arguments are provided in a separate list in Python, there is no way to intermix them. The few commands which relied on this have been extended so that a single multi-use flag handles the job of the individual multi-use flags.

These commands include:

  • polyAppendVertex : new append flag which can be used in place of the point, vertex, and hole flags.
  • polyAppend : new append flag which can be used in place of the point, edge, and hole flags.
  • polySplit : new insertpoint flag which can be used in place of the facepoint and edgepoint flags.
  • polyCreateFacet : the existing point flag as been modified so that it may be also used to specify holes.
  • roundConstantRadius : a new side flag replaces the use of sidea and sideb that are supposed to be intermixed.

The use of all of these flags is documented in the CommandsPython reference documentation.

In all cases, the flags are backwards compatible. All old flags have been left in place.

Arguments and objects

The curveOnSurface example above also illustrates another Python syntax requirement. Besides flags, Maya commands may also take arguments and objects. Arguments are values of a fixed type that are required by a command. For example, the move command takes three arguments representing the x, y, and z values for the move. Objects are the entities upon which a command operates (for example, an object in a scene or a UI element). There can be a variable number of objects for a command and sometimes they are implicit, based on the current selection list.

Objects and arguments are passed to commands as they would be in MEL, but they must be passed in the following order:

command arguments object flags/named arguments

This is different from MEL where the ordering requires that objects appear at the end of the argument list. However, Python requires that named arguments come after all other arguments.

Summary of argument types

The following table shows a summary of the flag (named argument) types you can use in the Maya Python module.

Flag type Example Comment

plain flag

MEL: ls -selection

Python: maya.cmds.ls( selection=True )

Flags with no arguments get a boolean True/False switch

flag with single argument

MEL: sphere -radius 10

Python: maya.cmds.sphere( radius=10 )

flag with multiple arguments

MEL: ambientLight -rgb 0.2 0.3 0.4

Python: maya.cmds.ambientLight( rgb=( 0.2, 0.3, 0.4 ) )

use a tuple to specify multiple arguments

multi-use flags

MEL: ls -type nurbsSurface -type transform

Python: maya.cmds.ls( type=['nurbsSphere','transform'] )

Use a list to hold the multiple flag values

multi-use flags with multiple arguments

MEL: curveOnSurface -d 3 -uv 0 0 -uv 0.3 0.5 -uv 0.5 0.6 surface1

Python: maya.cmds.curveOnSurface( 'surface1', degree=3, uv=[(0,0),(0.3,0.5),(0.5,0.6)] )

Use list of tuples.

(You can also use a tuple or tuples, a list of lists, or a tuple of lists.)

command arguments

MEL: move 2.0 1.0 1.0

Python: maya.cmds.move( 2.0, 1.0, 1.0 )

The same as MEL except arguments must come first

command arguments with flags

MEL: move -objectSpace 2.0 1.0 1.0

Python: maya.cmds.move( 2.0, 1.0, 1.0, objectSpace=True )

command objects

MEL: select nurbsSphere1

Python: maya.cmds.select( 'nurbsSphere1' )

Same as MEL

command objects with arguments and flags

MEL: move -objectSpace 2.0 1.0 1.0 nurbsSphere1

Python: maya.cmds.move( 2.0, 1.0, 1.0, 'nurbsSphere1', objectSpace=True )

Objects must come before flags

query where a flag/argument takes a value

MEL: skinCluster -q -inf;

Python maya.cmds.skinCluster (q=True, inf=True)

Query flag requires a boolean True.

query where a flag/argument does not take a value

MEL: skinCluster -inf joint1 -q -dr;

Python: skinCluster (q=True, inf='joint1', dr=True)

 

Standard input (stdin) implementation

Python supports reading from STDIN (standard input). In a Python script, this is accomplished by reading from sys.stdin or calling raw_input. When Maya is running in GUI mode (as opposed to batch mode), Maya intercepts these calls from Python and prompts you with a dialog box where you can type your input.

Maya overrides sys.stdin with its own implementation. If you want to use Python’s native stdin object, you can do so by referencing sys.__stdin__.

Examples

Enter one of the following in the Script Editor to display the Python STDIN dialog box:

  • Using raw_input
    raw_input()
    
  • Using sys.stdin
    import sys
    inp = sys.stdin.readline()
    
  • To customize the command prompt
    import maya.cmds as cmds
    inp = cmds.promptDialog(message='hello')
    

MEL/Python communication

A new MEL command—python—takes a string and passes it to be executed in Python. The python command attempts to convert the result into a MEL type.

python( "import maya.cmds" )
python( "maya.cmds.ls" )
Note:

Only strings with a single Python statement return a result. This is a limitation currently imposed by Python.

Python has a more sophisticated type system than MEL, so it is not possible to convert all Python data types into native MEL types. The python command converts those that it knows how to handle. For the rest, it requests a string representation of the object and returns that.

The following table shows the currently supported mappings:

Python Return Value MEL Conversion

string

string

unicode

string

int

int

float

float

list containing numbers, including at least one float

float[]

list containing only integers or longs

int[]

list containing a non-number

string[]

anything else

string

empty Python list

empty string array (string $array[])

Calling MEL from Python

To call MEL from Python, use the maya.mel.eval() function. It can do a better job of conversion than the MEL python command since Python has more flexible type support.

You must import the maya.mel module to use this command; that is:

import maya.mel as mm mm.eval("polySphere;")

Here is a table of the supported conversions:

MEL Return Value Python Conversion

string

string

int

int

float

float

vector

3-tuple of values

matrix

list of lists where each sub-list in the list contains one row of the matrix

string[]

list of strings

int[]

list of ints

float[]

list of floats

vector[]

list of 3-tuples

Positional arguments

Positional arguments refer to the arguments that UI elements pass to their callback scripts. For example, the callback MEL script for a float slider control could contain #1. The value of the float slider is substituted for this positional argument when the callback is run.

For Python, two different ways of substituting values from controls in callbacks are supported. If the callback is a string which is to be evaluated, then Maya does string substitution as in MEL. However, Python’s format operator is used to do the substitutions. The format operation is passed a dictionary of items for the substitution where the names of the values are 1, 2, and so on. For example:

maya.cmds.floatSlider( cc="print '%(1)s'" )

(The dictionary is applied to the string later, before it is executed. The floatSlider command formats the string with the current slider value before executing the script. You provide the format string and the UI element provides the dictionary for the format operation.)

The second style of Python callback uses a compiled function, where Maya passes the values as arguments to the function:

def doPrint( arg ):
	print arg
cmds.floatSlider( cc=doPrint )

With callback functions, you get an error message if your callback does not take the correct number of arguments.

def badStuff():
	print "bad"
cmds.floatSlider( cc=badStuff )

When you move the slider, you see this error:

# TypeError: badStuff() takes no arguments (1 given)

If you want to create a callback that works with any number of arguments, use a variable argument list:

def genericCallback( *args ):
	print( "args: " + str ( args ) )
cmds.button( command=genericCallback )