4

Question: is it possible to reverse engineer python objects into a string?


Info: I'm working on a project right now that distributes my prof's research across several dozen computers instead of just his. Being a good programmer I'm making it a generalized program that can be used for more than just his specific program. So the computers that will be running his code do not and will not have his .py files for them to import. The way I've gotten around this in the past is he just has to have everything in one file and pass the path to that file to my system which then imports that code as a from its state as a string (using the information gleaned from this question).

But that made me wonder. I can now import from a string and have the code execute fine and dandy. thats all well and good, but it made me think, is there a way for me to get around having to have him pass his code file to me? particularly I'm wondering something like this. say he has all of this in his file:

def hello():
    print "Hello world!"

upon importing this file "hello" would be added to the global namespace. but now I want to transfer it across the network. you can't call pickle on "hello" and have it work, I've tried, pickle out right refuses.

on the other end I have the node computers using "exec code in newMod.dict" to get the code created. so if I could take "hello" and push it through some function that returns to me "def hello():\n print \"Hello world!\"" so that my exec method could then run. I would be golden. I could then make it so he could have more than just 1 file because I could just reverse engineer any non-standard imports he has.

I'm honestly expecting the answer to be no, but i figured it is worth a shot. Simply stated again, I want to take an module that has been imported and convert it into a string.

6
  • 7
    There are already a gazillion Python frameworks to support distributed computing. If you really were a good programmer then you'd be using one of them rather than re-inventing the wheel. ;-) Commented Jul 3, 2011 at 20:24
  • 3
    also regarding good programming: not all good programmers are in agreement that more generalized is better. Chuck Moore, for example, believes that a good program solves the immediate problem with no hooks for future possible needs; one can always modify the program as needed. Commented Jul 3, 2011 at 20:30
  • @ David: well, cough being a good programmer I know I could do it sooo much better than what all those other frameworks have done. :p (though this is actually an exercise as well. So its a learning experience for me) @jco: valid point. I'm starting to question why I even made that remake between you two now. But I do plan on using this system formore than just his program, another prof has already asked to use it. Commented Jul 3, 2011 at 20:32
  • Converting it to a string won't work (at least it won't be feasible), but perhaps you can send code objects and wrapp them up in functions. Still quite some work and/or limited, so I'd suggest you go with an existing framework unless this is mainly for education. Commented Jul 3, 2011 at 20:32
  • @delnan: a lot for education. I've learned delightfully much about networking and python from this project. I had a certain level of dissatisfaction with the other frameworks out there. I'm going to get burnt for saying that I can just feel it. but they all seemed a little bit to much. I wanted a system that was as simple as can be. as it is now, you start the program on the server and the node programs on the clients and setup is complete. Perhaps I just didn't read the other frameworks well enough, perhaps they weren't well enough documented (annoyingly common). but here I stand. Commented Jul 3, 2011 at 20:35

2 Answers 2

1

Although it's not a good approach, you can pickle only the __code__ from the function...

>>> def foo():
...     print "Hello"

>>> import pickle
>>> code = pickle.dumps(foo.__code__)
>>> def bar():
...     pass

>>> bar()
>>> bar.__code__ = pickle.loads(code)
>>> bar()
Hello
Sign up to request clarification or add additional context in comments.

2 Comments

that works. and while it doesn't entirely accomplish what I dreamed of, it is a huge step in the right direction. how would you go about doing this for a class?
I think that I might be able to make an extension for the pickle class that will be able to do this through recursion. Look at a module, break it into it's parts and package each part one a time. but the basic answer to the question I had asked is honestly "no"
0

With marshal module you can persist code objects back and forth:

>>> source = """
... def hello():
...     print "Hello, world!"
... """
>>>
>>> code = compile(source, '<mycustomcode>', 'exec')
>>> class Module(object): pass
...
>>> module = Module()
>>> exec code in module.__dict__
>>> module.hello()
Hello, world!
>>> import marshal
>>> marshal.dumps(code)
'c\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00@\x00\x00\x00s\r\x00\x00\x00d\
x00\x00\x84\x00\x00Z\x00\x00d\x01\x00S(\x02\x00\x00\x00c\x00\x00\x00\x00\x00\x00
\x00\x00\x01\x00\x00\x00C\x00\x00\x00s\t\x00\x00\x00d\x01\x00GHd\x00\x00S(\x02\x
00\x00\x00Ns\r\x00\x00\x00Hello, world!(\x00\x00\x00\x00(\x00\x00\x00\x00(\x00\x
00\x00\x00(\x00\x00\x00\x00s\x0e\x00\x00\x00<mycustomcode>t\x05\x00\x00\x00hello
\x02\x00\x00\x00s\x02\x00\x00\x00\x00\x01N(\x01\x00\x00\x00R\x00\x00\x00\x00(\x0
0\x00\x00\x00(\x00\x00\x00\x00(\x00\x00\x00\x00s\x0e\x00\x00\x00<mycustomcode>t\
x08\x00\x00\x00<module>\x02\x00\x00\x00s\x00\x00\x00\x00'

Not sure if this is a good approach though...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.