Python program extension and Zope server tutorial using C language, pythonzope
There are several reasons you may want to extend Zope with C. Most likely, you have a ready-made C library that can help you do something, but you are not interested in converting it into Python. In addition, because Python is an explanatory language, any Python code that is called in large quantities will speed up your operation. Therefore, even if you have already written some extensions in Python, you still need to consider using C to write the most frequently called part. Either way, Zope extension starts with Python extension. In addition, extension of Python will bring you other benefits, because your code will be accessible from any Python script, not just from Zope. The only note here is that when writing this article, the current Python version is 2.1, but Zope can only run with Python 1.5.2. For the C extension, the two versions are not changed, but if you are interested in Python packaging for your library and want them to work in Zope, you must be careful not to use anything updated later than 1.5.2.
What is Zope?
Zope stands for "Z Object Publishing Environment (Z Object Publishing Environment)", which is an Application server implemented in Python. "That's great," you said. "But what exactly does the application server mean ?" An Application Server is a long-term running process that provides services for "active content. The Web server calls the application server during running to build the page.
Python Extension: Interesting and beneficial
To expand Zope, you must first extend Python. Although Python extension is not as complex as brain surgery, it is not as leisurely as walking in the park. There are two basic components for Python extension. The first is obviously the C code. I will discuss it right away. The other part is the installation file. The Installation File describes the module by providing the module name, the position of the module's C code, and all the compiler logos you may need. This file is preprocessed to create makefile (on UNIX) or MSVC ++ project file (on Windows ). Let's talk about it first-Python on Windows is actually compiled using Microsoft compiler. Python.org users also recommend using MSVC ++ to compile extensions. Obviously, you should be able to successfully persuade GNU compilers, but I have not tried it yet.
In any case, let's define a module called 'foo. The 'foo' module has a function called 'bar. When we want to use it, we can use import foo; to import this function to a Python script, just like importing any module. The Installation File is very simple:
Listing 1. A typical Installation File
# You can include comment lines. The *shared* directive indicates# that the following module(s) are to be compiled and linked for# dynamic loading as opposed to static: .so on Unix, .dll on Windows.*shared*# Then you can use the variables later using the $(variable) syntax# that 'make' uses. This next line defines our module and tells# Python where its source code is.foo foomain.c
Write code
So how do we actually write the code that Python knows how to use? The foomain. c (you can name it as needed) file contains three items: A method table, an initialization function, and other code. The method table simply associates the function name with the function, inform Python of the parameter transfer mechanism used by each function (you can choose to use the general location parameter list or the mixed list of location parameters and keyword parameters ). Python calls the initialization function when the module is loaded. The initialization function completes all the initialization operations required by the module, but more importantly, it also returns a pointer to the method table to Python.
Let's take a look at the C code of our small foo module.
Listing 2. A typical Python extension module
#include <Python.h>/* Define the method table. */static PyObject *foo_bar(PyObject *self, PyObject *args);static PyMethodDef FooMethods[] = { {"bar", foo_bar, METH_VARARGS}, {NULL, NULL}};/* Here's the initialization function. We don't need to do anything for our own needs, but Python needs that method table. */void initfoo(){ (void) Py_InitModule("foo", FooMethods);}/* Finally, let's do something ... involved ... as an example function. */static PyObject *foo_bar(PyObject *self, PyObject *args){ char *string; int len; if (!PyArg_ParseTuple(args, "s", &string)) return NULL; len = strlen(string); return Py_BuildValue("i", len);}
In-depth research
Let's take a look at the code. First, you must include Python. h. Unless you have set the file path in the include path, you may need to include the-I flag in the installation file to point to the file.
The initialization function must be named init <Module name>. In our example, It is initfoo. The name of the initialization function is undoubtedly all the information about the module that Python knows when loading the module. This is also the reason why the name of the initialization function is so rigid. By the way, the initialization function must be the only global identifier in the file that is not declared as static. This is more important for static links than dynamic links, because non-static identifiers are globally visible. This is not a big problem for dynamic links. However, if you plan to link everything during compilation, you have not declared all the things that can be declared static as static, you may encounter name conflicts.
Now let's look at the actual code to see how the parameters are processed and how the returned values are passed. Of course, everything is a Python object. What you get from the parameter is a reference to the "this" object (this is used for object methods and is NULL for old-fashioned functions like bar () without parameters) and a parameter tuples stored in args. You use PyArg_ParseTuple to retrieve your parameters, and then use Py_BuildValue to pass the results back. These functions (and more) are archived in the "Python/c api" section of the Python document. Unfortunately, there is no simple function list by name, and the document is arranged by topic.
Note that the function returns NULL if an error occurs. If the return value is NULL, an error occurs. If you want to make Python better, you should throw an exception. I will instruct you to read the document on how to do this.
Compilation Extension
All the remaining problems are the compilation module. You can do this in two ways. First, run make-f Makefile. pre. in boot according to the instructions in the document. This will use your Setup to compile a Makefile. Then you can use this Makefile to compile your project. This method only applies to UNIX. For Windows, there is a script named "compile. py" (see references later in this article ). The original script is hard to find; I found a large number of changed copies from a mailing list from Robin Dunn (wxPython's behind-the-scenes workers. This script can work on UNIX and Windows. On Windows, it will compile MSVC ++ project files starting from your Setup.
To compile, you must make the included files and libraries available. Python standard Zope installation does not contain these files, so you need to install Python from www.python.org (see references. On Windows, you must also obtain the config. h file from the PC directory where the source code is installed. It is a manual version of config. h compiled for you by UNIX installation. Therefore, you should have it on UNIX.
After all these operations are completed, you will get a file with the extension ". pyd. Put this file in the "lib" directory under the Python installation directory (Python is located in the "bin" directory under Zope, so your extension ends at the "bin/lib" directory, that's strange .) Then you can call it, just like calling any source Python module.
>>> import foo; >>> foo.bar ("This is a test"); 14
Here, my first question is how to use C to define classes visible from Python. In fact, I may have asked a wrong question. In the examples I have studied, Everything specific to Python is only done in Python, and only the C function exported from your extension is called.
Take it to Zope
Once your Python extension is completed, the next step is to enable Zope to work with it. You can select several methods, but to some extent, the method in which you want your extension to work with Zope will first affect the way you compile the extension. The basic methods for using Python (and C extension) code in Zope are as follows:
- If the function is simple, you can treat it as a variable. These are called "external methods ".
- More complex classes can be called from Zope scripts (this is a new feature of Zope 2.3 ).
- You can define a Zope Product, and then expand it with ZClass (a set of ready, Web-accessible objects) and use it in scripts, publish it based on its own permissions (its instance is treated as a page ).
Of course, your own applications can use these combinations.
Create external Method
The simplest way to call Python from Zope is to make your Python code an external method. The external method is to put the Python function in the "Extensions" directory under the Zope installation directory. Once such a Python file exists, you can go to any folder, select "add external method", and add the variable that calls the function to be used. Then you can add the DTML field to any page that shows the call results in the folder. Let's take a simple example of using the Python extension foo. bar defined above.
First, let's look at the extension itself: we put it in a file named foo. pyd. Remember, this file is located in the Extensions directory under Zope. In order to proceed smoothly, of course, the foo. pyd we created above must be in the Python library located in bin/lib. A simple package for this purpose may look like this:
Listing 3. A simple external method (File: Extensions/foo. py)
import foodef bar(self,arg): """A simple external method.""" return 'Arg length: %d' % foo.bar(arg)
It's easy, isn't it? It defines an external method "bar" that can be appended to any folder on the Zope management interface ". To call our extension from any page in the folder, simply insert a DTML variable reference, as shown below:
<dtml-var bar('This is a test')>
When you view our page, the DTML field will be replaced by the text "Arg length: 14. In this way, Zope is extended with C.
Zope Script: Cliff Notes
Zope script is a new function of Python 2.3 that is intended to replace external methods. All external methods can be achieved, and they can be better integrated with security and management systems to provide more flexibility in integration, it also has many accesses to all Zope functions published in the Zope API.
A script is basically a short Python program. It can define classes or functions, but is not required. It is installed as an object in the Zope folder, and then it can be treated as a DTML variable or called (just like an external method) to call or "from the Web" (in Zope, it means it will be called as a page) to call it. Of course, this means that the script can generate a response to form submission like a CGI program, but there is no CGI overhead. It is indeed a great feature. In addition, the script has the right to access the caller or caller object (through the "context" Object), the folder where the object is located (through the "container" Object), and other fragmented information. To obtain