Python module import question? (Maya 2013)

Hi guys,

I ran into a ‘module’ object has no attribute error when trying to execute a function in Maya through a custom menu. Looking for some help to sort this out.
env: Windows 7, Maya 2013

I set up a custom folder structure as below:
main_folder
script_folder
[INDENT]init.py[/INDENT]
[INDENT]function01.py[/INDENT]
userSetup.py

I then set up maya script environment variable to specify the path to the userSetup.py.

userSetup.py

def function01():
    import script_folder
    ### menu creation stuff
    cmds.menuItem(p=customMenu, l='function label', c='import script_folder;script_folder.fucntion01()')

init.py

import maya.cmds as cmds
try:
    from function01 import *
except:
    print 'something is wrong'

It seems to me the code is executed just fine as I am able to see and interact with the custom menu created in Maya until when I execute the function01, Maya throws me a ‘module’ object has no attribute ‘function01’ error. Did I not import the function01 properly or something?

Thanks!

a) you have a typo in your sample : fucntion01 where you want function01. Dunno if this is the real code or not.

b) You might want to check out these threads:

for a more compact way of putting functions into UI callbacks, using partial or callable objects

If function01.function01() accepts dummy arguments (*args, **kwargs) you can just do this:


import script_folder.function01

def create_menu():
    # do stuff
    cmds.menuItem(p=customMenu, l='function label', c=script_folder.function01.function01)

[QUOTE=jasonhtechart;20655]
init.py

import maya.cmds as cmds
try:
    from function01 import *
except:
    print 'something is wrong'

It seems to me the code is executed just fine as I am able to see and interact with the custom menu created in Maya until when I execute the function01, Maya throws me a ‘module’ object has no attribute ‘function01’ error. Did I not import the function01 properly or something?

Thanks![/QUOTE]

I think your problem is:

from function01 import *

It should be:

from script_folder.function01 import *

Or:

from script_folder import *

Thanks guys. I fixed the typo in the original post where there is a missing colon for function01().

paradigm3d, I have tried both of your suggestions but in vain. Still getting the same error message.

'module' object has no attribute 'function01'

does function01.py have a function called “function01” defined?

yes I attach a sample code of function01.py as below.

function01.py

import maya.cmds as cmds
def fucntion01(arg1, arg2):
    cmds.setAttr(stuff)
    cmds.setAttr(stuff2)

Sorry guys, I have typos that cause confusions. I update the sample file structure and code as below.

root_folder
vray_script_folder
[INDENT]init.py[/INDENT]
[INDENT]function01.py[/INDENT]
[INDENT]function02.py[/INDENT]
[INDENT]function03.py[/INDENT]
userSetup.py

An environment variable is specified with the path pointing to the userSetup.py in the root_folder.

userSetup.py

def sampleFunction():
    import vray_script_folder
    ### menu creation stuff
    cmds.menuItem(p=customMenu, l='function label', c='import vray_script_folder; vray_script_folder.function01()')
    cmds.menuItem(p=customMenu, l='function label', c='import vray_script_folder; vray_script_folder.function02()')

init.py

import maya.cmds as cmds
try:
    from function01 import *
    from function02 import *
except:
    print 'something is wrong'

function01.py

import maya.cmds as cmds
def function01(arg1, arg2):
    cmds.setAttr(stuff)
    cmds.setAttr(stuff2)

When I execute the function01 in Maya, I am stilling the ‘module’ object has no attribute ‘function01’ error.

Why are you importing * from init. It makes it very difficult to see where things are coming from with * alone, but to further mask it in init ? Couldn’t you just do this:


def sampleFunction():
    import vray_script_folder
    ### menu creation stuff
    cmds.menuItem(p=customMenu, l='function label', c='from vray_script_folder import function01; function01.function01()')

Multiple * imports run the risk of redefining things accidentally - if function01.py and function02.py have identically named functions your version will only have the last defined one in vray_script_folder

You’re also making extra work for yourself. The only reason to import the parent package first is if it does some silent initialization that you need to have done before getting the children - otherwise it’s just an organizational construct. You could just do this in your handler:


def sampleFunction():
    import vray_script_folder.function01 as func1   # to avoid the long names
                                                   # (but I like long names - they make it clear what's going on  :)  )
    ### menu creation stuff
    cmds.menuItem(p=customMenu, l='function label', c=func1.function01)  # just assign the callable, don't use the strings

Lastly, by try/catching the import error you don’t know if you’ve actually got the names at all. Let them fail so you know they are broken and fix them. “Fail early, fail often” is the mantra :slight_smile: