[Maya / Python] Best practice for variable/function scope?

I’m in the process of switching over to Maya, and I’m having a bit of toruble finding a good way of keeping all the global variables etc in check.

For MAXScript, I kept everything nice and neat by embedding things inside of structures, and by keeping the entire code inside of brackets, like the following:

(   --Open bracket at the start of the script allows local variables to be assigned in the main body of code
	struct Settings                           --a structure which contains variables which need to be accessed globally (but do not remain in global memory after execution is finished)
	(
	 myVar = "Blah",
	 mySize = 24
	)

	struct CommonFunctions                  -- a structure containing commonly used functions which need to be accessed globally
	(
		fn FunctionA =
		(
			local myVar = "Hello"
			print myVar
		)
	)


       Settings.myVar = "30"                            --editing/accessing the variables inside of the first structure
       CommonFunctions.functionA                    --running a function inside of the second structure
) --close bracket for the entire code.	

The end result of this is that everything is super neat, and you almost never get problems with variable/function conflicts. Does anyone have any suggestions for a similar setup with maya Python?

Pep-8 and the Google python style guide are good places to start.

Python doesn’t use brackets for organization, it will take some adjustment (and you will not miss them, I promise!).

[QUOTE=rgkovach123;26021]Pep-8 and the Google python style guide are good places to start.

Python doesn’t use brackets for organization, it will take some adjustment (and you will not miss them, I promise!).[/QUOTE]

Thanks, those guides look really useful. Every piece of code i’ve written so far seems to follow the ‘Do not do this’ examples in those guides :p:

I still can’t quite find the exact answer to what I was looking for though. Would it be a good idea to look into classes, and embedding functions etc inside of them?

In your example above, you would probably use a module (fancy name for python file). Keep everything in there, variables, functions, classes and import the module. This way all your codes are organized by module and not in one big file

You could use classes to do the same thing technically.

While a bit overkill (there was a talk I one watched where they talked about if your class is just an init then you don’t need that class, which I agree with) it is essentially the same as struct. The other option is to use a dictionary where instead of…

 
property1=value1
property1=value2

you have

module_properties = { 
"property1":value1,
"property2":value2
}

Thanks, I think i’m starting to understand now.

-So, I have a python module called “myModule”, which contains a function called “myFunc”.
-Inside the main script, I import myModule and then run the function by doing “myModule.myfunc()”
-If I have another module called “otherModule” which also has a function called “myFunc”, it won’t conflict because it would be run as “otherModule.myFunc()”

is this right? :stuck_out_tongue:

yes, but it would be a good idea to not reuse the same function name, because you can do things like this:

from myModule import *
from otherModule import *

which would result in otherModule.myFunc overwriting myModule.myFunc

[QUOTE=Twiggy;26028]Thanks, I think i’m starting to understand now.

-So, I have a python module called “myModule”, which contains a function called “myFunc”.
-Inside the main script, I import myModule and then run the function by doing “myModule.myfunc()”
-If I have another module called “otherModule” which also has a function called “myFunc”, it won’t conflict because it would be run as “otherModule.myFunc()”

is this right? :P[/QUOTE]

That is correct, the module keeps it in scope within it. Properties inside that module are also within that modules scope but can be accessed and changed once imported.

Ah I see. I guess it would be wise to have a naming convention which tries to prevent conflicts like that then.

rather than worrying about naming convention, just import the module and use the dotted names



import  module1
import module2

def example():
     return module1.myfunc() + module2.myfunc()

or use the ‘as’ to provide alias and avoid confusion


from module1 import myfunc as myfunc_1
from module2 import myfunc as myfunc_2

[QUOTE=Theodox;26032]rather than worrying about naming convention, just import the module and use the dotted names



import  module1
import module2

def example():
     return module1.myfunc() + module2.myfunc()

or use the ‘as’ to provide alias and avoid confusion


from module1 import myfunc as myfunc_1
from module2 import myfunc as myfunc_2

[/QUOTE]

Yeah… I guess that does seem like the most straighforward way!

There was one more thing which i’m a little confused about… How does maya keep all of these things in it’s memory inbetween executions, and is there a way to make it forget them after execution is finished. For example:

In a blank tab do:


def myFunc():
   print Hello

and then execute it. It’s now stored in Maya’s memory somewhere, so even in a blank tab you can run myFunc(). The same thing applies for any variables etc. I always find this kind of confusing when I’m writing scripts- sometimes it can cause weird outcomes if it remembers stuff from previous executions, and even that typical problem of a script only working the second time you execute it. For MAXscript this is easily solved by just putting the entire script in brackets, giving it it’s own little scope which dissapears after the script is done.

Also… one more problem (I promise this is the last one)! So i’ve set up the basic stucture of importing a module. If I then change something in that module, and import again, it doesn’t seem to reflect the changes I’ve made until maya is restarted.

Maya’s script editor is global. Everything stored in modules in local. Once you import a module, it will remain until maya is shut down (or you manually delete it with del). you will need to use reload(myModule) to refresh the code if you are iterating.

[QUOTE=rgkovach123;26040]Maya’s script editor is global. Everything stored in modules in local. Once you import a module, it will remain until maya is shut down (or you manually delete it with del). you will need to use reload(myModule) to refresh the code if you are iterating.[/QUOTE]

Brilliant! I think that’s just about everything I need to know to get started with a basic infrastructure.

Thanks for the help everyone, you’ve probably saved me hours of running round in circles!