我想看看注释或字符串是否保留在$py.class文件中,所以我尝试了使用Jython 2.5.3和Jython 2.7.0进行实验。(在我的例子中,原始的.py文件不会公开,但$py.class文件是已发布的.jar的一部分;我不希望某些注释可见)
C:\tmp\jython>java -jar c:\app\java\lib\jython-standalone-2.7.0.jar
Jython 2.7.0 (default:9987c746f838, Apr 29 2015, 02:25:11)
[Java HotSpot(TM) 64-Bit Server VM (Oracle Corporation)] on java1.8.0_152
Type "help", "copyright", "credits" or "license" for more information.
>>> import py_compile
>>> py_compile.compile('loose_lips.py')
其中loose_lips.py包含:
def loose_lips_sink_ships(x):
"""CM1 Doc comment"""
# CM2 line comment
"""
CM3 Another multiline string that doesn't do anything
but is not a doc comment
"""
return x+1
"""
CM4 Yet another comment that could theoretically
be optimized out, since we can never get here
"""
我预测CM1将是结果输出中唯一保留的字符串内容,因为它在Python中具有定义良好的语义——它是docstring,因此它被填充到loose_lips.loose_lips_sink_ships.__doc__
。剩下的代码没有理由出现在任何运行时代码中
如果我在Python2.7.14中运行py_compile.compile('loose_lips.py')
(或者只运行import loose_lips
),那么它将生成一个包含字节码的.pyc文件,并且如预测的那样,唯一保留的文本是CM1
如果在Jython 2.5.3或Jython 2.7.0中运行py_compile.compile('loose_lips.py')
,则生成的$py.class文件包含CM1和CM3
为什么CM3会在运行时保留?Jython解释器是否有任何外部可见的行为(例如保留源代码?)需要保留多行字符串?我有什么办法可以阻止它吗
我在http://www.javadecompilers.com上反编译了$py.class文件,结果如下:
import org.python.core.PyRunnableBootstrap;
import org.python.core.CodeBootstrap;
import org.python.core.CodeLoader;
import org.python.core.PyFunction;
import org.python.core.PyString;
import org.python.core.Py;
import org.python.core.PyObject;
import org.python.core.ThreadState;
import org.python.core.PyFrame;
import org.python.core.PyCode;
import org.python.compiler.Filename;
import org.python.compiler.MTime;
import org.python.compiler.APIVersion;
import org.python.core.PyRunnable;
import org.python.core.PyFunctionTable;
//
// Decompiled by Procyon v0.5.36
//
@APIVersion(36)
@MTime(1578883953709L)
@Filename("loose_lips.py")
public class loose_lips$py extends PyFunctionTable implements PyRunnable
{
static loose_lips$py self;
static final PyCode f$0;
static final PyCode loose_lips_sink_ships$1;
public PyObject f$0(final PyFrame pyFrame, final ThreadState threadState) {
pyFrame.setline(1);
pyFrame.setlocal("loose_lips_sink_ships", (PyObject)new PyFunction(pyFrame.f_globals, Py.EmptyObjects, loose_lips$py.loose_lips_sink_ships$1, (PyObject)PyString.fromInterned("CM1 Doc comment")));
pyFrame.f_lasti = -1;
return Py.None;
}
public PyObject loose_lips_sink_ships$1(final PyFrame pyFrame, final ThreadState threadState) {
pyFrame.setline(2);
PyString.fromInterned("CM1 Doc comment");
pyFrame.setline(9);
PyString.fromInterned(" \n CM3 Another multiline string that doesn't do anything\n but is not a doc comment\n ");
pyFrame.setline(11);
final PyObject add = pyFrame.getlocal(0)._add((PyObject)Py.newInteger(1));
pyFrame.f_lasti = -1;
return add;
}
public loose_lips$py(final String s) {
loose_lips$py.self = this;
f$0 = Py.newCode(0, new String[0], s, "<module>", 0, false, false, (PyFunctionTable)loose_lips$py.self, 0, (String[])null, (String[])null, 0, 4096);
loose_lips_sink_ships$1 = Py.newCode(1, new String[] { "x" }, s, "loose_lips_sink_ships", 1, false, false, (PyFunctionTable)loose_lips$py.self, 1, (String[])null, (String[])null, 0, 4097);
}
public PyCode getMain() {
return loose_lips$py.f$0;
}
public static void main(final String[] array) {
Py.runMain(CodeLoader.createSimpleBootstrap(new loose_lips$py("loose_lips$py").getMain()), array);
}
public static CodeBootstrap getCodeBootstrap() {
return PyRunnableBootstrap.getFilenameConstructorReflectionBootstrap((Class)loose_lips$py.class);
}
public PyObject call_function(final int n, final PyFrame pyFrame, final ThreadState threadState) {
switch (n) {
case 0: {
return this.f$0(pyFrame, threadState);
}
case 1: {
return this.loose_lips_sink_ships$1(pyFrame, threadState);
}
default: {
return null;
}
}
}
}
目前没有回答
相关问题 更多 >
编程相关推荐