如何在Python中从字符串创建实例的对象

时间:2014-02-21 04:18:39

标签: python eval maya repr

我正在使用Python 2.5在Maya中工作,编写动态热键管理器类并且在尝​​试分配特定于实例的命令时遇到了麻烦,因为nameCommands在mel中表示为字符串。我最终得到的命令如下:

<bla.Bla instance at 0x0000000028F04388>.thing = 'Dude'

我已经看过很多关于repr和eval的话题,但下面的测试示例失败了。

class Foo:
    pass

f = Foo()
f.thing = 'Jeff'
rep = repr(f)
y = eval(rep) # errors here
name = y.thing

# Error: invalid syntax
# Traceback (most recent call last):
#   File "<maya console>", line 7, in <module>
#   File "<string>", line 1
#     <__main__.Foo instance at 0x00000000294D8188>
#     ^
# SyntaxError: invalid syntax # 

我认为我想要的是从字符串中获取该实例的正确对象的某种方法。 如果我知道它看起来像什么,我可以将字符串格式化为可评估的命令。 see my cgtalk post for more usage info

SO相关主题:

这个说不可能,但用户也想要一个用例,我希望我已经提供过。 How to obtain an object from a string?

其他: When is the output of repr useful? How to print a class or objects of class using print()? Allowing the repr() of my class's instances to be parsed by eval() Main purpose of __repr__ in python how do you obtain the address of an instance after overriding the __str__ method in python Python repr for classes how to use 'pickle'

2 个答案:

答案 0 :(得分:2)

要使eval起作用,需要覆盖内置__repr__函数。我没有看到你提到这一点,所以我认为你没有这样做。我正在粘贴一段时间后我写的代码片段。只是为了示范。在此示例中,eval起作用,因为__repr__被覆盖:

class element :
    def __init__(self, a, m):
        self.name = a ;
        self.atomic_mass = m ;

    def __str__(self):
        return "{0} has atomic mass {1}".format(self.name, self.atomic_mass)

    def __repr__(self):
        return "element(\"{0}\", \"{1}\")".format(self.name, self.atomic_mass)

H = element("Hydrogen", 1.00794)
print H
print repr(H)
print eval(repr(H))

更多信息:http://www.muqube.com/python/string-representation-of-python-objects/

答案 1 :(得分:1)

找到了一个似乎对我here有用的方法,使用id作为字符串和ctypes

class Foo:
    pass

f = Foo()
f.thing = 'Jeff'

import ctypes    
long_f = id(f)
y = ctypes.cast(long_f,ctypes.py_object).value
name = y.thing

这里是Maya中的一个示例用法;

command = ("python(\"ctypes.cast(%s,ctypes.py_object).value.thing=False\")")%(id(self))
nameCommand = cmds.nameCommand( 'setThingOnPress', annotation='', command=command )
cmds.hotkey( keyShortcut='b', name=nameCommand)