【问题标题】:reverse engineering python to strings将python逆向工程为字符串
【发布时间】:2011-09-27 18:16:42
【问题描述】:

问题:是否可以将 python 对象逆向工程为字符串?


信息:我现在正在开展一个项目,该项目将我教授的研究分布在数十台计算机上,而不仅仅是他的。作为一名优秀的程序员,我正在使它成为一个通用程序,不仅可以用于他的特定程序。因此,将运行他的代码的计算机没有也不会有他的 .py 文件供他们导入。我过去解决这个问题的方法是他只需将所有内容都放在一个文件中并将该文件的路径传递给我的系统,然后将该代码作为字符串从其状态导入(使用从收集的信息this 问题)。

但这让我感到奇怪。我现在可以从字符串导入并让代码执行得很好。这一切都很好,但这让我想,有没有办法让我不必让他将他的代码文件传递给我?特别是我想知道这样的事情。说他的档案里有所有这些:

def hello():
    print "Hello world!"

在导入此文件时,“hello”将被添加到全局命名空间中。但现在我想通过网络传输它。你不能在“你好”上打电话给pickle并让它工作,我试过了,pickle out right拒绝。

在另一端,我让节点计算机使用“newMod.dict 中的执行代码”来创建代码。因此,如果我可以使用“hello”并将其推送给返回给我的某个函数“def hello():\n print \"Hello world!\"",这样我的 exec 方法就可以运行了。我会是金色的。然后我可以做到,这样他就可以拥有不止一个文件,因为我可以对他拥有的任何非标准导入进行逆向工程。

老实说,我希望答案是否定的,但我认为值得一试。再次简单地说,我想把一个已经导入的模块转换成一个字符串。

【问题讨论】:

  • 已经有大量的 Python 框架来支持分布式计算。如果你真的是一个优秀的程序员,那么你会使用其中一个而不是重新发明轮子。 ;-)
  • 还有关于好的编程:并不是所有好的程序员都同意越通用越好。例如,查克·摩尔认为,一个好的程序可以解决眼前的问题,而无需为未来可能的需求提供任何挂钩;可以随时根据需要修改程序。
  • @David:嗯, 作为一个优秀的程序员,我知道我可以做得比所有其他框架做得更好。 :p(虽然这实际上也是一个练习。所以它对我来说是一种学习经验)@jco:有效点。我开始质疑为什么我现在还要在你们两个之间重拍。但我确实计划使用这个系统,而不仅仅是他的程序,另一位教授已经要求使用它。
  • 将它转换为字符串是行不通的(至少它不可行),但也许您可以发送代码对象并将它们包装在函数中。仍然有很多工作和/或有限,所以我建议你使用现有的框架,除非这主要用于教育。
  • @delnan:很多教育。我从这个项目中学到了很多关于网络和 python 的知识。我对那里的其他框架有一定程度的不满。我会因为说我能感觉到它而被烧毁。但他们似乎都有点过分。我想要一个尽可能简单的系统。就像现在一样,您在服务器上启动程序并在客户端上启动节点程序,设置完成。也许我只是没有很好地阅读其他框架,也许它们的文档记录不够好(令人讨厌的普遍)。但我站在这里。

标签: python import reverse-engineering


【解决方案1】:

虽然这不是一个好方法,但您只能从函数中腌制__code__...

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

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

>>> bar()
>>> bar.__code__ = pickle.loads(code)
>>> bar()
Hello

【讨论】:

  • 行得通。虽然它并没有完全实现我的梦想,但这是朝着正确方向迈出的一大步。您将如何在课堂上这样做?
  • 我认为我可以为泡菜类做一个扩展,它可以通过递归来做到这一点。查看一个模块,将其分解为多个部分,并一次将每个部分打包。但我所问问题的基本答案是老实说“不”
【解决方案2】:

使用marshal module,您可以来回持久化代码对象:

>>> 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'

虽然不确定这是否是一个好方法...

【讨论】:

    猜你喜欢
    • 2021-08-23
    • 1970-01-01
    • 2011-07-14
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 2011-11-18
    • 2011-11-17
    相关资源
    最近更新 更多