python eval for pymel node

42 views
Skip to first unread message

Zhen Huang

unread,
May 2, 2019, 5:24:01 AM5/2/19
to Python Programming for Autodesk Maya
Hi , 

I have a question about python build-in function 'eval ' , please check out the example code below :

## create a polySphere , default name : 'pSphere1'

import pymel.core as pm
from pymel.core import nt 

# initialize a pymel transform node 
pymelShpere = pm.PyNode('pSphere1')
# put it to a dict
testDict = {0:pymelShpere}
# convert it to str which can be stored as string in file basic data 
strMark = str(testDict)

# now read it back , if scene has the pShere1 , it will work perfectly 
newDict = eval(strMark)

# now delete the pShpere1 , and try to convert data to dict , failed because the pymel nt will try to initialize the string 'pShere1' to pymel node 
newDict =eval(strMark)


My question : if I have lots of nodes store in a string data which convert from dict , is there a way to just make it out , just ignore error part or if node not exists it just convert from nt to string name ?
if pSphere2 not exist then return 
                                                              {0:nt.Transform('pSphere1'), 1:'pSphere2' }



Any idea is very much welcome , big thanks !!!

Justin Israel

unread,
May 2, 2019, 6:47:45 AM5/2/19
to python_in...@googlegroups.com
I would advise staying away from the eval() approach. Not only is it going to be inflexible for your current goal, it also can cause unwanted execution of arbitrary logic. A random code snippet that deletes files could be set on a node and your code would blindly execute it as your own user. You don't want random code being evaluated like that. 

A better approach would be to use a proper serialisation format like json or pickle (protocol version 1 for ascii format). This would allow you to read the data back into a dictionary and then evaluate each value and filter what does and does not exist in the scene. 


--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/3f87dcf5-3171-47e7-bec5-a56d550513d1%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

zhen huang

unread,
May 2, 2019, 9:06:55 AM5/2/19
to Python Programming for Autodesk Maya
Hi Justin , 

Thank you ! I've tried the json even can't dumps the pymel node data . This is why I looked for the eval solution . 
Please check the error out :
    Error: TypeError: file C:\Program Files\Autodesk\Maya2017\bin\python27.zip\json\encoder.py line 184: nt.Transform(u'pSphere2') is not JSON serializable

Thanks and Regards , 

在 2019年5月2日星期四 UTC+8下午6:47:45,Justin Israel写道:


On Thu, May 2, 2019, 9:24 PM Zhen Huang <qeej...@gmail.com> wrote:
Hi , 

I have a question about python build-in function 'eval ' , please check out the example code below :

## create a polySphere , default name : 'pSphere1'

import pymel.core as pm
from pymel.core import nt 

# initialize a pymel transform node 
pymelShpere = pm.PyNode('pSphere1')
# put it to a dict
testDict = {0:pymelShpere}
# convert it to str which can be stored as string in file basic data 
strMark = str(testDict)

# now read it back , if scene has the pShere1 , it will work perfectly 
newDict = eval(strMark)

# now delete the pShpere1 , and try to convert data to dict , failed because the pymel nt will try to initialize the string 'pShere1' to pymel node 
newDict =eval(strMark)


My question : if I have lots of nodes store in a string data which convert from dict , is there a way to just make it out , just ignore error part or if node not exists it just convert from nt to string name ?
if pSphere2 not exist then return 
                                                              {0:nt.Transform('pSphere1'), 1:'pSphere2' }



Any idea is very much welcome , big thanks !!!

I would advise staying away from the eval() approach. Not only is it going to be inflexible for your current goal, it also can cause unwanted execution of arbitrary logic. A random code snippet that deletes files could be set on a node and your code would blindly execute it as your own user. You don't want random code being evaluated like that. 

A better approach would be to use a proper serialisation format like json or pickle (protocol version 1 for ascii format). This would allow you to read the data back into a dictionary and then evaluate each value and filter what does and does not exist in the scene. 


--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

Justin Israel

unread,
May 2, 2019, 3:40:51 PM5/2/19
to python_in...@googlegroups.com


On Fri, May 3, 2019, 1:06 AM zhen huang <qee...@gmail.com> wrote:
Hi Justin , 

Thank you ! I've tried the json even can't dumps the pymel node data . This is why I looked for the eval solution . 
Please check the error out :
    Error: TypeError: file C:\Program Files\Autodesk\Maya2017\bin\python27.zip\json\encoder.py line 184: nt.Transform(u'pSphere2') is not JSON serializable

Thanks and Regards , 

Convert the PyMel node into a fullpath string and store that. When you deserialize it back to a dict, you can convert the full path back into a PyMel node. 

Alternatively you may try using the cPickle module as it may be able serialize PyMel nodes. Probably better that you just use the full path though. 

To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/09731b94-8047-4136-bd12-a66781210224%40googlegroups.com.

Zhen Huang

unread,
May 2, 2019, 9:01:29 PM5/2/19
to Python Programming for Autodesk Maya
Hi Justin , 

Will try cPickle module , thank you! Let you know if it's working .

Best , 

在 2019年5月3日星期五 UTC+8上午3:40:51,Justin Israel写道:
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

Zhen Huang

unread,
May 3, 2019, 12:38:37 AM5/3/19
to Python Programming for Autodesk Maya
Hi Justin , 

cPickle can deserialize pymel node , and like eval it can't convert back if the node not exists .

Thank you , 


在 2019年5月3日星期五 UTC+8上午3:40:51,Justin Israel写道:
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

Justin Israel

unread,
May 3, 2019, 12:43:08 AM5/3/19
to python_in...@googlegroups.com
On Fri, May 3, 2019 at 4:38 PM Zhen Huang <qeej...@gmail.com> wrote:
Hi Justin , 

cPickle can deserialize pymel node , and like eval it can't convert back if the node not exists .

Thank you , 

Likely because the pymel node constructor wants to validate and fail if it doesn't exist, as opposed to letting you have a representation of a node that may or may not exist. This is why I was suggesting just storing full string paths and then converting each one back into a pymel node and being able to handle some that do not exist. If you use strings then you can use json.
 
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/70ea3488-20ed-4926-baf3-6e19de71e479%40googlegroups.com.

Zhen Huang

unread,
May 6, 2019, 8:53:45 PM5/6/19
to Python Programming for Autodesk Maya
Sorry for late .

Yeah , if everything is string then no problem , if there is no possibility then will use string instead . 

Big thanks , hope you are doing well.



在 2019年5月3日星期五 UTC+8下午12:43:08,Justin Israel写道:


To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

Alon Zaslavsky

unread,
May 14, 2019, 3:24:57 PM5/14/19
to python_in...@googlegroups.com
I'm not sure what your end goal is. But if it's just to get whats in the dictionary, use the iteritems dictionary method.

dict = {'A': 'sphere1', 'B': 'sphere2'}
for key, val in dict.iteritems():
    print key, val

I tested it with the value being a pymel class object and it works too.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.


--
Alon Zaslavsky
Puppet TD

Justin Israel

unread,
May 14, 2019, 3:58:32 PM5/14/19
to python_in...@googlegroups.com


On Wed, May 15, 2019, 7:24 AM Alon Zaslavsky <al...@tippett.com> wrote:
I'm not sure what your end goal is. But if it's just to get whats in the dictionary, use the iteritems dictionary method.

dict = {'A': 'sphere1', 'B': 'sphere2'}
for key, val in dict.iteritems():
    print key, val

I tested it with the value being a pymel class object and it works too.

The issue isn't actually the container for which the data is stored or read. It's the serialization of the PyMel node and then reading it back in later. The constructor of the PyMel node expects the object in the scene to exist otherwise you get an exception. So the suggestion was to serialize to a format that wouldn't automatically run the PyMel node constructors so that each one can be manually converted. 

Zhen Huang

unread,
May 23, 2019, 11:27:30 PM5/23/19
to Python Programming for Autodesk Maya
Yes , converting to string before storing in file will absolutely no problem , what I except is there any solution to intervene the reading process .
For example if we use cPickle , maybe we can create monkey patch for the cPickle.load function . Let reading process running without raising any error for pymel node.



在 2019年5月15日星期三 UTC+8上午3:58:32,Justin Israel写道:
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.


--
Alon Zaslavsky
Puppet TD

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

Justin Israel

unread,
May 23, 2019, 11:34:13 PM5/23/19
to python_in...@googlegroups.com
On Fri, May 24, 2019 at 3:27 PM Zhen Huang <qeej...@gmail.com> wrote:
Yes , converting to string before storing in file will absolutely no problem , what I except is there any solution to intervene the reading process .
For example if we use cPickle , maybe we can create monkey patch for the cPickle.load function . Let reading process running without raising any error for pymel node.

For pickle, you could wrap each pymel node in a custom class that implements the pickle protocol. This would allow you to store just the path when it gets serialized, and then when it gets deserialised, you can construct and return a pymel node again:

For json you have similar support by using a custom default function when encoding, and a custom object_hook when decoding back again:
https://docs.python.org/2/library/json.html#encoders-and-decoders



To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.


--
Alon Zaslavsky
Puppet TD

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/fdbc67c6-43c4-41a1-bb73-277e2d7ce368%40googlegroups.com.

Zhen Huang

unread,
May 24, 2019, 2:41:36 AM5/24/19
to Python Programming for Autodesk Maya
Hi Justin , 

Thank you , those doc looks great , will let you know if I can figure out a specific solution .

Best , 

在 2019年5月24日星期五 UTC+8上午11:34:13,Justin Israel写道:


To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.


--
Alon Zaslavsky
Puppet TD

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages