2005年5月9日

Compile python code? 编译蟒蛇程序?

You cannot but there are ways to hide your python code by compiling part of your program. How about a C program with a main() and use python's C API? Well,
pyrex
can do that.



All you have to do for a stand alone C program in Pyrex are:



cdef extern from "Python.h":
void Py_Initialize()
void Py_Finalize()
void PySys_SetArgv(int argc, char *argv[])

# Declare extension init function as a C function.
cdef public void initdemo()

# Define main() and declare it as "public"
cdef public int main(int argc, char *argv[]):
Py_Initialize() # Init Python environment
PySys_SetArgv(argc, argv) # Fill in sys.argv
initdemo() # Init our Pyrex generated main module.
# Do something here...
Py_Finalize() # When done, clean up Python env.





The following is a real example which actually do something. We use the re module to demostrate the power of python here:



demo.pyx:


cdef extern from "Python.h":
void Py_Initialize()
void Py_Finalize()
void PySys_SetArgv(int argc, char *argv[])

cdef extern from "stdio.h":
int printf(char *format, ...)

cdef public void initdemo()

def regex(msg):
import re
a = re.findall(r'as\w*', msg)
return a

cdef public int main(int argc, char *argv[]):
Py_Initialize()
PySys_SetArgv(argc, argv)
initdemo()
msg = 'Jump it as high as an ass, asshole!'
print 'Searching "as" from "%s"' % msg
m = regex(msg)
for i in m:
print 'Match:', i

cdef int count
count = len(m)
printf("Total: %d\n", count)
Py_Finalize()

# vim:ts=8:sw=4:expandtab



Makefile: Link with libpython.

all: demo

demo: demo.c
gcc -g -O2 -I/usr/include/python2.3 -lpython2.3 -o demo demo.c

demo.c: demo.pyx
pyrexc demo.pyx

.PHONY:
all



Run ./demo now will show you how things go. We hide everything in demo.pyx now!



As you can see, every C function that is used inside .pyx need to be explicitly declared in a cdef extern from "cheader.h": block. Other than that, Pyrex also cannot do list comprehension and generator. So do your generator or comprehension in a .py module and import to the .pyx.



And of cause if you don't write pure C inside .pyx, the resulting program will not be faster than a pure .py program.

没有评论: