Python Developer's Handbook
Python Developer's Handbook
The Python Developers Handbook is designed to expose experienced developers to Python and its uses. Beginning with a brief introduction to the language and its syntax, the book moves quickly into more advanced programming topics, including embedding Python, network programming, GUI toolkits, JPython, Web development, Python/C API, and more. Python is an interpreted, object-oriented programming language. Its syntax is simple and easy to learn, and it encourages programmers to write and think clearly. The Python Developers Handbook is carefully written, well-organized introduction to this powerful, fast-growing programming language for experienced developers.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing 2002, O'Reilly & Associates, Inc.
CONTINUE >
Introduction
When I was a little kid, I had this dream where a snake would rule and dominate the entire world (actually, I guess that a penguin was also part of the dreambut never mind). I didn't pay much attention to the fact at that time because I thought the dream was caused by an overexposure to all those Japanese series that were popping up on the screens. Later, in my teenage years, there was this science project where I had to spend some time studying snakes to display at an exhibition. After analyzing Red Tail boas and coral snakes, I found this 3-year old giant of 10 feet, 40+ pounds. Instantly, I recognized that snake as being the same one that I had seen in my dream years before. Its name was Python, but at that time, I still couldn't figure out what was the relationship between that reptile and the world domination. Fifteen years ago, I was trying to select a channel in my old TV set, when a special program caught my attentionA huge animated foot was dancing in the opening titles. After the program started, there were a group of funny guys who were playing jokes about parrots and lumberjacks. After watching tons of episodes and all their five films, I decided to write a book about them. I noticed that they were called Python too. Maybe that was the answer. That troupe would dominate the entire world. I wanted to let everyone know about it. Initially I had planned to write about the actors and their most famous sketches, but I had to abandon the idea when I realized that my editors wouldn't give me enough time to write a book of approximately 25,030 pages. That would be a nice bestseller, though. Even though none of the previous facts has really happened, both have at least one thing in commonthe name Python. Python is also a scripting language whose name's origin has much to do with the English troupe than with the legless reptile. This book will guide you step-by-step through the universe of Python, a fantastic programming language that can help you to implement solutions for almost all types of IT challenges that you might face. Almost all IT-related tasks, such as the manipulation of database systems, or the design of Web-driven applications can be managed using Python. Maybe that's the answer for my dream. For the last couple of months, I've been trying to organize all the information about Python that I have available, arranging them in this book. I can't say that I have included every little thing in the book, but I do know that I have covered the most important aspects of the Python language. Note that along the 5month development period of this book, Python had several version upgrades, which made things way more difficult to organize. So, I apologize if something important is missing. This book is organized into 18 chapters and some additional appendixes, where each one covers a specific aspect of the language. Inside each chapter, you will find many hints about how to use Python
to meet your needs. As you might agree with me, it is impossible to cover every single aspect of the language in such a complete and up-to-date way. That's why I choose to provide Web links to other sources of material that I think will be useful for your learning. What this book covers? A short answer is The book starts with a very extensive review of the language and the modules that come as part of the Python distribution. It goes through Object-Oriented Programming, Networking, Web Development, Graphical Interfaces, and other important topics. The last chapter covers JPython, a version of Python that runs in Java systems. A long answer is Chapter 1 explains what Python is, why Python must be used, where to get support and how to go through each installation process. Chapter 2 is a complete review of the Python programming language. By the end of this chapter, you will learn how to create Python applications. Chapter 3 shows which main modules extensions are currently available and for what purposes they can be used. The focus here is to expand your knowledge about the Python libraries, showing the resources that you already have available in the Python programming language. Chapter 4 demonstrates how to handle exception situations and how to avoid error messages. Chapter 5 introduces the OO methodology in a very complete and direct way. You will be able to easily create and use objects and classes in your programs after reading this chapter. Chapter 6 discusses extending and embedding Python. You will learn how to extend Python methods using other languages and how to call Python methods from within other applications. Chapter 7 explains objects interfacing and distribution. The information provided in this chapter explains objects distribution and how to use them from within other systems. Chapter 8 shows all the database options available within Python. For those that don't know anything about database yet, it explains how databases work and how to execute basic SQL statements. Chapter 9 provides very useful information concerning the use and manipulation of some advanced topics, including images, sounds, threads, and scientific Python Modules.
Chapter 10 explains basic network concepts and invites you to play with these concepts using Python programs. Chapter 11 provides information concerning how to use Python for Internet development. It also introduces you to some well-known Python third-party Web applications. Chapter 12 provides information concerning how to use Python for scripting programming. Chapter 13 provides information concerning how to use Python for data parsing and manipulation, such as XML parsing and mail processing. Chapter 14 shows what the available GUI options for graphic designing in Python are. Chapter 15 provides Tkinter information. For those that don't know yet, Tkinter is the standard Python GUI. Chapter 16 shows some performance suggestions, and guides you through the process of writing clean code within style. Chapter 17 introduces a handful programming tools. You will learn how to go through all the development stages without fear, including how to debug, compile, and distribute Python applications. Chapter 18 demonstrates how easy it is to mix Java and Python using JPython. Now that you know that you have a lot of interesting material to learn, I suggest you accept my hint: The best way to read this book is by sitting on a comfortable beach chair, or laying on your bed, and relaxing. If for some reason, if you think the topic is getting boring, just turn the page and go to another chapter until you find something that you like. Later, you can return to where you originally left. This book can be read from the start, or you can go directly to the chapter that teaches a specific functionality. It's your choice! So, what are you waiting for? Turn this page at once, and get ready to start dominating the world.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark 2002, O'Reilly & Associates, Inc. CONTINUE >
<= Return to book index About the Author Acknowledgments Tell Us What You Think! Introduction I: Basic Programming 1. Introduction Introduction to Python Why Use Python? Main Technical Features Python Distribution Installing and Configuring Python Python and Other Languages Patches and Bugs List PSA and the Python Consortium Summary 2. Language Review Language Review The Shell Environment Programs Built-In Data Types Operators Expressions Control Statements Data Structures Functions and Procedures Modules and Packages Input and Output File Handling Summary Code Example 3. Python Libraries Python Libraries Python Services types UserDict UserList operator
traceback linecache pickle cPickle copy_reg shelve copy marshal imp parser symbol token keyword tokenize pyclbr code codeop pprint repr py_compile compileall dis new site user __builtin__ __main__ The String Group Miscellaneous Generic Operational System Optional Operational System Debugger Profiler Internet Protocol and Support Internet Data Handling Restricted Execution Multimedia Cryptographic UNIX Specific
SGI IRIX Specific Sun OS Specific MS Windows Specific Macintosh Specific Undocumented Modules Summary 4. Exception Handling Exception Handling Standard Exceptions (Getting Help from Other Modules) Raising Exceptions Catching Exceptions try/finally Creating User-defined Exceptions The Standard Exception Hierarchy Summary Code Examples 5. Object-Oriented Programming Object-Oriented Programming An Introduction to Python OOP Python Classes and Instances Methods Handling Special Methods Inheritance Polymorphism Encapsulation Metaclasses Summary Code Examples II: Advanced Programming 6. Extending and Embedding Python Extending and Embedding Python The Python/C API Extending Compiling and Linking Extension Modules SWIGThe Simple Wrapper Interface Generator Other Wrappers Embedding Summary Code Examples
7. Objects Interfacing and Distribution Object Interfacing and Distribution Interfacing Objects Introduction to COM Objects Implementing COM Objects in Python Distributing Objects with Python Summary Code Examples 8. Working with Databases Working with Databases Flat Databases DBM (Database Managers) Databases Object Serialization and Persistent Storage The ODBC Module ADO (ActiveX Data Objects) Using SQL Python DB API Summary 9. Other Advanced Topics Other Advanced Topics Manipulating Images Working with Sounds Restricted Execution Mode Scientific Computing Regular Expressions Threads Summary Code Examples III: Network Programming 10. Basic Network Background Networking Networking Concepts HTTP Accessing URLs FTP SMTP/POP3/IMAP NewsgroupsTelnet and Gopher Summary 11. Web Development
Web Development Configuring Web Servers for Python/CGI Scripts Third-Party Internet Applications Other Applications Site Management Tools Summary 12. Scripting Programming Web Programming An Introduction to CGI The cgi Module Creating, Installing, and Running Your Script Python Active Scripting Summary 13. Data Manipulation Parsing and Manipulating Data XML Processing XML-RPC XDR Data Exchange Format Handling Other Markup Languages MIME Parsing and Manipulation Generic Conversion Functions Summary IV: Graphical Interfaces 14. Python and GUIs Python GUI Toolkits The Tkinter Module Overview of Other GUI Modules Designing a Good Interface Summary 15. Tkinter Introduction to Tcl/Tk Tkinter Geometry Management Handling Tkinter Events Tkinter Widgets Designing Applications PMWPython Mega Widgets Tkinter Resources Summary
V: Developing with Python Chapter 16. Development Environment Building Python Applications Development Strategy Integrated Development Environments IDLE Pythonwin Summary 17. Development Tools The Development Process of Python Programs Compiling Python Editing Code Python Scripts Generating an Executable Python Bytecode Interpreter Debugging the Application Profiling Python Distributing Python Applications Summary VI: Python and Java Chapter 18. JPython Welcome to JPython Java Integration Downloading and Installing JPython The Interpreter The JPython Registry Creating Graphical Interfaces Embedding jpythonc Running JPython Applets Summary VII: Appendixes A. Python/C API Python/C API The Very High Level Layer Reference Counting Exception Handling
Standard Exceptions Utilities Abstract Objects Layer Concrete Objects Layer Initialization, Finalization, and Threads Memory Management Defining New Object Types B. Running Python on Specific Platforms Python on Win32 Systems Python on MacOS Systems Python on UNIX Systems Other Platforms C. Python Copyright Notices Python 2.0 License Information Python's Copyright Notice (version 1.6) Python's Copyright Notice (until version 1.5.2) Copyright Notice of the profile and pstats Modules Copyright Notice of JPython with OROMatcher Copyright Notice of JPython without OROMatcher D. Migrating to Python 2.0 Python 1.6 or Python 2.0. Which One to Choose? New Development Process Enhancements Expected Code Breaking
Web Development > Python Developer's Handbook > About the Author
CONTINUE >
CONTINUE >
Acknowledgments
I would like to render my acknowledgments to the ones who most shared my life during the last few months while I wrote this book, giving me support and inspiration to conclude this beautiful work.
God My parents, Neuza & Josu Thank you all! My wife, Renata
In addition, I would like to express gratitude to my entire family and friends for being so friendly, and for supporting my wife and I in our decision to move to the United States. and of course, for sending Brazilian goodies and baby gifts to us by mail! Beth, Bruno, Carol, Cleber, Dinda Teca, Djalminha, Gabriel Jorge, Gustavo, Jorge, Juliana, Lucas, Matheus, Ney, Patricia Beatriz, Penha, Rafael, and Victor. And if I forgot about you, consider yourself included in this list! Thanks folks! (Valeu galera!) Also, I would like to thank everyone at Macmillan for the patience and comprehension that they had every time I was late in my milestones. A special thank you goes to my Technical Editor James Henstridge for providing outstanding suggestions and remarks about the contents of this book. Rhonda, you were great correcting my English mistakes and reviewing my writings! Thanks Katie, thanks Mandie. I do know I gave you a lot of work, didn't I? Dawn, Amy, Scott, even though we didn't have much contact, I know that you were all there every time this book needed you. God bless you all! And last, but not least, Shelley, thanks for discovering me! I still remember that day, March 14, when I got your email asking me if I had ever considered authoring. Well, this book says everything. Thank you very much for this opportunity.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark 2002, O'Reilly & Associates, Inc. CONTINUE >
Web Development > Python Developer's Handbook > Tell Us What You Think!
CONTINUE >
Mail:
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark 2002, O'Reilly & Associates, Inc. CONTINUE >
CONTINUE >
CONTINUE >
Chapter 1. Introduction
Nobody expects the Spanish Inquisition This chapter explains to you why Python is considered to be a good language, why it should be used, what its main features are, where you can find support, and how to go through each installation process.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark 2002, O'Reilly & Associates, Inc. CONTINUE >
Web Development > Python Developer's Handbook > 1. Introduction > Introduction to Python
CONTINUE >
Introduction to Python
Python is an open source language that is getting a lot of attention from the market. It combines ease of use with the capability to run on multiple platforms because it is implemented focusing on every major operating system. Guido van Rossum created the language nearly 11 years ago and since then, Python has changed through the years, turning itself into one of the most powerful programming languages currently available. Python is a good prototype language. In just a few minutes, you can develop prototypes that would take you several hours in other languages. It also embodies all object-oriented concepts as part of its core engine. Therefore, creating programming object-oriented applications in Python is much easier than it would be in other languages such as Java or C++. As I just said, Python is an open source project. Consequently, it is truly free. No copylefts or copyrights are involved in its license agreement. You can change it, modify it, give it away, sell it, and even freely distribute it for commercial use. Its copyright only protects the author from legal problems that might occur if someone decides to sue the author for errors caused by using Python, or if someone else tries to claim ownership of the language. Maybe you still don't know Python, but many companies are out there using it. The problem is these companies don't want to go public talking about it because they think that using Python without getting the attention of their competitors is a good strategy. Okay, I know that you are curious to know who in the world is using Python. Organizations like Industrial Light and Magic, Yahoo!, Red Hat, and NASA are some of companies that run Python applications. Note You can always check out the latest news about Python by visiting http://www.python.org/News.html.
Nowadays, many developers are contributing to Python's support. That means that, currently, a lot of people are testing and designing modules for the language. If you spend some time visiting Python's
official Web site, you can get a list of several development groups that are working hard to give Python some support to new technologies, such as XML and image processing. Both Perl and Java already have a large group of programmers who are very devoted to their programming languages, and, today, Python is starting to get there. Notice that Python is a language extremely easy to code if you have ever programmed before. Guido claims to have fun every time he has to do something using Python. Learning Python through this book will be exciting too. Soon, you will have some practice and understand the reason I say that. In this chapter, I give you a quick overview of Python's main features. The other chapters of this book cover in detail the topics that I mention next. Python!? What Is It? Let's define Python: Python is an interpreted, high-level programming language, pure object-oriented, and powerful serverside scripting language for the Web. Like all scripting languages, Python code resembles pseudo code. Its syntax's rules and elegant design make it readable even among multiprogrammer development teams. The language doesn't provide a rich syntax, which is really helpful. The idea behind that is to keep you thinking about the business rules of your application and not to spend time trying to figure out what command you should use. Quoting Guido van Rossum"Rich syntax is more of a burden than a help." It is also true (and later you will have a chance to check it out) that Python is interactive, portable, easy to learn, easy to use, and a serious language. Furthermore, it provides dynamic semantics and rapid prototyping capabilities. Python is largely known as a glue language that connects existing components. It is embeddable in applications from other languages (C/C++, Java, and so on), and it is also possible to add new modules to Python, extending its core vocabulary. Python is a very stable language because it has been in the market for the last 10 years and also because its interpreter and all standard libraries have their source code available along with the binaries. Distributing the sources for everyone is a good development strategy because it makes developers from all around the world work together. Anyone can submit suggestions and patches to the official development team, led by Python's creatorGuido van Rossum. Guido is the coauthor of the second implementation of the scripting language ABCa language that was used, mostly, for teaching purposes in the '80s by a small number of people. Python is directly derived from ABC.
Python was born in an educational environment, in the Christmas of 1989 at CWI in Amsterdam, Netherlands. Guido was a researcher at CWI at that time. Initially, it was just a project to keep him busy during the holidays. Later, it became part of the Amoeba Project at CWI. Its first public release was in February of 1991. For a long time, Python's development occurred at CNRI in Reston, VA in the United States. In June of 2000, the Python development team moved to PythonLabs, a member organization of the BeOpen Network, which is maintained by the lead developers of the Python language, including Guido. On October 27, 2000 the entire PythonLabs Team has left BeOpen.com because of some mutual disagreements concerning the future of Python. The Team is now working for Digital Creations (the makers of Zope - http://www.digicool.com/), and Guido has just announced the idea of creating a nonprofit organization called Python Software Foundation (PSF)in order to take ownership of future Python developments. By the way, Python was named after the British comedy troupe Monty Python. It had a comedy series called Monty Python's Flying Circus on the BBC in the '70s. Guido is a huge fan. As many Monty Python quotes are throughout the chapters of this book as in any other Python book. That is something of a standard behavior among Python authors, and I won't be the one who will try to change it. Note "Nobody expects the Spanish Inquisition" is one of the most famous quotes that is always recited by Guido. Each chapter of this book is headed by a famous Monty Python quote.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 1. Introduction > Why Use Python?
CONTINUE >
long and strange lines of code. Therefore, less training is a direct result. Companies don't need to spend much time to have their programmers coding in Python. Once you start learning Python, you can do useful coding almost immediately. And after some practice, your productivity will suddenly increase. You can design a high-level, object-oriented programming code in a friendly and interpreted Python environment. This feature works great for small tasks. Fast to Code Python provides fast feedback in several ways. First, the programmer can skip many tasks that other languages require him to take. Therefore, it reduces both the cost of program maintenance and the development time. If necessary, Python enables a fast adaptation of the code. You can change the highlevel layer of your application without changing the business rules that are coded within your modules. The interactive interpreter that comes with the Python distribution brings rapid development strategies to your project. In spite of traditional programming languages that require several distinct phases (such as compiling, testing, and running) and other scripting languages that require you to edit the code outside the execution environment, Python is a ready-to-run language. Every time you use Python's interactive interpreter, you just need to execute the code you have. A direct benefit of this feature over Perl is the way you can interactively test and play around with your code. Python provides a bottom-up development style in which you can build your applications by importing and testing critical functions in the interpreter before you write the top-level code that calls the functions. The interpreter is easily extensible. It enables you to embed your favorite C code as a compiled extension module. Reusability Python encourages program reusability by implementing modules and packages. A large set of modules has already been developed and is provided as The Standard Python Library, which is part of the Python distribution. You can easily share functionality between your programs by breaking the programs into modules, and reusing the modules as components of other programs. Portability Besides running on multiple systems, Python has the same interface on multiple platforms. Its design isn't attached to a specific operational system because it is written in portable ANSI C. This means that you can write a Python program on a Mac, test it using a Linux environment, and upload it to a Windows NT server. Everything mentioned here is possible because Python supports most of its
features everywhere. However, you must know that some modules were developed to implement specific mechanisms of some operational systems and, of course, programs that use those modules don't work in all environments. But, wait a minute. This problem affects only some specific modules. Usually, you can make most of your applications run on multiple platforms without changing one line of code. How many other languages can claim this type of behavior? Python is well integrated with both UNIX and Windows platforms. The Macintosh environment also supports Python applications, even though it doesn't provide a full set of solutions yet. But don't worry. Developers are currently working on that. Object-Oriented Programming Usually, scripting languages have object-orientation support included in the language as an add-on. However, everything in Python, as in Smalltalk, is designed to be object-oriented. You can start programming using non-OO structures, but it doesn't take too long for you to find out that it is much simpler if you use its OO features. Some of the implemented OO functionality in Python is inheritance and polymorphism. Overall Conclusion The overall conclusion is that Python is a fantastic language that provides all these features for free. I assure you that if you want all these features in any other language, you will have to buy costly thirdpart libraries. Every detail in Python's project is part of a huge plan to have the most used and necessary features of other languages in a unique environment. If someone asks which are the cases that Python doesn't provide the best solution, I would have just one answer: applications that require huge amounts of low-level data processing. That is said because, as you already know, Python is an interpreted language; and for that reason, it is proven to be a little bit slower than compiled languages. However, even in cases such as this, Python makes it easy to replace bottlenecks with C implementations, which speeds things up without sacrificing Python's features. If you have already decided that Python is exactly what you need, be sure to go through all the following chapters. It will be fun.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 1. Introduction > Main Technical Features
CONTINUE >
Python provides a huge list of useful built-in elements (the language's basic data structure) along with many special operations that are required to correctly process them. This list is as follows:
q
Data typessuch as strings, tuples, lists, hash tables, and so on Operationslike searching routine statements (in and not in), sorting, and so on
Development Flow Even though it doesn't have any compilation or linking process, Python supports byte compilation. The compiled code is saved in an intermediate language called bytecode that can be accessed by any system that has a Python virtual machine. This feature offers a kind of portability similar to the one that Java also offers. Applications can be used in several different systems without the need for compilation. Furthermore, you can create a standalone executable and securely distribute your applications. Clear Syntax and a Diversity of Useful Lexical Elements The way Python is organized seems to encourage object-oriented programming because everything is an object. In addition to that, it has various helpful lexical elements, such as the following:
q
Operator overloadingThe same operator has different meanings according to the elements that are being referenced. Dynamic typingYou don't need to assign types in your code. After you assign a value to an object, it instantly knows what type it should assume. You can even assign different types to the same variable within the same program. Name resolutionEach structure (module, class, and so on) defines its own scope of names. IndentationThere are no line-end markers as in Java and C++, where programmers need to use semicolons. Python defines indentations by using block structures.
Embeddable and Extendable Python can be embedded in applications written in many other programming and scripting languages. Whenever you need to have a programmable interface for your applications, give Python a chance. Python is well known for easily gluing everything. Python also enables you to add low-level modules to the interpreter. Those built-in modules are easily written in C and C++. Extension modules are easily created and maintained using Python. For tasks like this, you can develop components in C and run them through Python subclasses.
Objects Distribution Python can be used to implement routines that need to talk to objects in other applications. For example, Python is a great tool to glue Windows COM components. Besides that, Python also has a few CORBA implementations that enable you to use cross-platform distributed objects, as well. Databases Python has interfaces to all major commercial databases, provides several facilities to handle flat-file databases, and implements object-persistence systems that can save entire objects to files. But the greatest database feature is that Python defines a standard database API, which makes it easy to port applications to different databases. GUI Application You can create applications that implement graphical user interfaces (GUIs), which are portable to many system calls, libraries, and windowing systems such as Windows MFC, Macintosh, Motif, and UNIX's X Window System. This is possible because many GUI bindings were developed for Python. The Python distribution is bundled with Tkinter, a standard object-oriented interface to the Tk GUI API that has become the official GUI development platform for Python. Introspection You can develop programs in Python to help in the creation of other programs in Python. The most important examples are the Debugger and the Profiler. And there is even more: Python has an Integrated Development Environment (IDLE) developed using Python for use with Python. Third-Party Projects Integration The Python Extension NumPy (Numerical Extensions to Python) along with the Python Library PIL (Python Imaging Library) prove that everyone who contributes to the language can make his projects almost a required complement to the standard Python distribution.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 1. Introduction > Python Distribution See All Titles
CONTINUE >
Python Distribution
At the time of this writing, the last official version of Python is version 2.0, released on October 16, 2000. Prior to that, we had version 1.6 final released on September 5, 2000, and version 1.5.2 released on April 13, 1999. After release 2.0, Guido plans to work on two more 2. x releases that might be available by the end of 2000 or January 2001. After that, all his attention will be dedicated to a total Python redesign, a future project called Python 3000. Despite many rumors that have been spread in the Python community, Guido affirms that this mythical version is "not as incompatible as people fear." This book was planned to be a Python 1.5.2 book. But it turned out to cover the migration from 1.5.2 to 2.0. That's why you will see much of the text focusing on release 1.5.2, and special notes about release 2.0. The latest Python source codes for your UNIX, Windows, or Mac system are maintained under the CVS revision control system. CVS (Concurrent Version System) is a version control system that stores and manages the code that is in process of development. Remember! The source code available through CVS might be slightly different from the one released along with the last official release. If you want to download the source code from CVS, go to http://www.python.org/download/cvs.html and check out the instructions that show how to get the appropriate CVS client for your system. The Python CVS tree is currently hosted by SourceForge at http://sourceforge.net/projects/python/. It is normal to have more than one Python installation in your system. You can install the official version in one location and build the CVS source code in some other location. Guido van Rossum, the creator of Python, maintains high-quality Python documentation at Python's official Web site. You can download Python's documents from http://www.python.org/doc/. There are versions in HTML, PostScript, and PDF. Part of this documentation is included in the distribution packages. The 1.5.2 distribution comes with five tutorials that you should wisely go through:
q
The Library Reference The Language Reference Extending and Embedding Python The Python/C API
The first two manuals above cover how to setup the the Python Distribution Utilities ("Distutils") in order to create source and built distributions. The former uses the module developer's point-of-view, and the latter uses the end-user's point-of-view. The last manual shows how to follow some standard guidelines for documenting Python. Python's current documentation is also available for download at http://www.python.org/doc/current/download.html. More information about Python 2.0 documentation and downloading can be found at http://www.PythonLabs.com. System Requirements Python runs on many platforms. Its portability enables it to run on several brands of UNIX, Macintosh, Windows, VMS, Amiga, OS/2, Be-OS, and many others. Most all platforms, which have a C compiler, support Python. You can try to compile Python yourself in any architecture you want because the source code is distributed along with the binaries. You should also have a text editor because sometimes it is easier to use an application like emacs, pico, notepad, or other similar one, instead of using the interpreter or the graphical development environment. If you are using emacs, make sure that python-mode is installed because it makes it a lot easier to develop Python code. See Chapter 17, "Development Tools," for details. After downloading the source code at http://www.python.org/download/download_source.html, you
can carefully play around with it and if you want to go one step further, port it to another platform. If you are using UNIX, it's going to be necessary to have tar and the GNU gzip programs in-hand in order to unpack the downloaded files. If you are using Windows, you must have WinZip available for the task. GNU gzip is available at http://www.gnu.org/software/gzip/gzip.html and WinZip is available at http://www.winzip.com. Depending on the system that you are using, you might need to get a C compiler in case you have need to download the source code instead of the binary distribution. Right now it is okay to use the binary distributions (whenever they are available), but when you become more confident with the language, you might want to build a Python version that uses your own extensions. So, you will need to have a C compiler. Remember that you are free to use Python's source code any way you want. The full C source code is freely available for download.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 1. Introduction > Installing and Configuring Python
CONTINUE >
Up-to-date versions for the most popular distributions are always available. Keep this URL because we will go to the site later to download other Python items that we might need. UNIX Environment The UNIX distribution is, in my opinion, the best distribution. It comes with POSIX bindings, and it supports environment variables, files, sockets, and so on. It is perfect for all flavors of UNIX.
Linux Installation
These days, all the major Linux distributions include Python, which makes your life simple because you don't have to download the files. Sometimes, Python is even automatically installed for you. Just make sure that you have the latest version. If you already have Python installed in your machine, and you've got a new Python RPM package, you must execute the following command in order to update the RPM: (Note that this filename reflects the 1.5.2 version.)
Otherwise, run the following command in your Linux prompt to install the RPM package.
When the installation process is over, check to see whether everything went fine by typing python at the prompt. You should get access to the Python interpreter, and when you are satisfied, press Ctrl+D to leave it. Perfect! Now you are ready to start coding in Python. In case you are using a Linux system that doesn't offer RPM support, you need to download the source code and compile it in your machine. Or, check whether your Linux distribution included Python. Instructions for compiling Python are provided in Chapter 17.
Other UNIX Systems
If you are running a UNIX system other than Linux, you need to download the source code and compile it in your own machine. Download the file py152.tgz from http://www.python.org/download/download_source.html. Note that this file corresponds to version 1.5.2. You might need to change the filename for the latest version. Following the instructions listed in the README file of the distribution will show you how to build and install the source code. Macintosh Environment MacPython is a Python version available for the Macintosh. Jack Jansen maintains it, and you can have full access to the entire documentation at his Web site. Currently, version 1.5.2 is available for download at http://www.cwi.nl/~jack/macpython.html. Beta versions from version 1.6 are also available. You can also download this distribution at Python's official Web site at http://www.python.org/download/download_mac.html. The full distribution is available in one unique file that also contains Tkinter and an interactive development environment. Windows Environment The Win32 and COM extensions by Mark Hammond are the result of an excellent work that is successfully reducing the distance between the overall performance of Python for UNIX and Python for Windows platforms. The following instructions show how to install the Python version for Windows systems. Note that to install the Win32 extensions, you need to install a separate package called Win32all-xxx.exe. You should replace the xxx with the number of the latest available release. The installation process is very straightforward within Win32 systems (Windows 95/98/2000 and NT). Go to the Python for Windows download page at http://www.python.org/download/download_windows.html and choose a location. If the location you selected isn't available at the moment, choose a mirror site. Let's download the py152.exe file (Python's version 1.5.2). Now that you have downloaded the file, save it to a location on your local hard disk. Double-clicking the file will launch an Installation Wizard as shown in Figure 1.2.
Figure 1.2. PythonWin's Installation Wizard guides you through a very simple installation process.
Select everything and confirm the selections. The installation process will start and after Python is installed, you will be asked if you also want to install Tcl/Tk (see Figure 1.3). I strongly suggest that you install it too because later you will learn how to create GUI interfaces using Tkinter. After you confirm it, the Wizard will guide you through Tcl's 8.0.5 for Windows installation. Choose the full installation, confirm it, and that's it. Your Windows system is fully configured to use both PythonWin and IDLE.
Figure 1.3. Installing Tcl/Tk now enables you to create GUI applications later.
I suggest that you spend some time going through all the documentation that was installed in your machine. Right now you might have everything already set up in your environment. If you decide later to download and build the source code, download the same source code that is provided for UNIX systems at http://www.python.org/download/download_source.html. Get the file py152.tgz and follow the instructions listed in the README file. It clearly explains how you could use Microsoft Visual C++ 5.0 to build the source code. See Chapter 17 for more details. If you are interested in downloading Python 2.0, the following link takes you directly to its download page. http://www.pythonlabs.com/products/python2.0/download_python2.0.html At PythonLabs, you have the source tarball available to build Python from the source in the platform of your choice. Note that if you are running Windows, you can download and run the Windows installer as well. The following links cover the 2.0 distribution. News about Python 2.0 http://www.pythonlabs.com/products/python2.0/news.html Python 2.0 Manuals
http://www.pythonlabs.com/doc/manuals/python2.0/ Python 2.0 - The new license http://www.pythonlabs.com/products/python2.0/license.html Note A special note is necessary here to let you know that Python 2.0 doesn't run a separate Tcl/Tk installer anymore. It installs all the files it needs under the Python directory. This was made to avoid conflicting problems with other Tcl/Tk installations that you might have on your system.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
installing Python MacPython Python installing and configuring 2nd 3rd 4th Python 2.0 downloading links 2nd PythonLabs Web site PythonWin Installation Wizard RPM package installing Linux running Windows insttaller source code Python downloading 2nd 3rd source tarball tarball (source) Tcl/Tk installer Web sites Python source code 2nd 3rd PythonLabs Windows installing Python 2nd Windows installer downloading and running wizards PythonWin
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 1. Introduction > Python and Other Languages
CONTINUE >
Python's array constructs don't have the same number of problems that arrays written in C have. Most of the memory allocation and reference errors that we easily get when coding C/C++ programs are eliminated as Python performs automatic memory management. Python checks array references for boundary violations. In many cases, developing an application in Python requires much less code than an equivalent application in C.
In general, Python is a great tool to test C/C++ applications. Python adds some contribution to C/C++ projects by gluing components and handling interfaces to test them. In addition to C/C++, Python is often compared to Perl, Java, and Tcl.
Python Versus Perl Python is easier to learn than Perl, and it presents a more readable code. Perl is an excellent language too. Perl is great for work that requires text manipulation and data extraction, and it is also a great language for system administrators. The Windows distribution of Perl is apparently pretty good, so it can be used productively under Windows. However, Perl is much more productive when used in a UNIX environment. Python's productivity is platform-independent. Another important difference is that Python was designed to be fully object-oriented and Perl had object-orientation implemented later as an add-on to the language. One problem with Perl is that because "there's more than one way to do it," different programmers in large projects might know different subsets of the language and will not be able to read each other's code. Python Versus Tcl Python's syntax is much clearer than Tcl's. Besides, it is the fastest one, and it needs less C extensions than those Tcl requires when doing the same job. Similar to Tcl, Python uses Tk as its standard GUI. Also, Python has more data types than just strings. Python Versus Smalltalk The following list shows some differences between Python and Smalltalk:
q
Python has scalability because it can handle small routines and large applications equally well. Python is much easier to learn than Smalltalk. Python enables the use of C and C++ code in programs that require a good performance because it is extensible. As most of Smalltalk's users come from the scientific society, the Numeric Python Extension becomes helpful by covering many mathematical aspects and making them easily written in Python.
Python Versus Java Python offers dynamic typing and a rapid development environment that requires less code and no compilation phase. Although Python runs slower than Java, it is the more portable one.
JPython
It's a new Python implementation that is 100% written in Java. You can use all the features of Python
languages along with the entire universe of Java classes. The integration between JPython and Java is better than the integration between Python and C++ because JPython can use Java classes without needing a wrapper generator. Several other reasons why you should consider giving JPython a try are as follows:
q
JPython is interactive, as is CPython. JPython applications can import Java classes directly and, whenever required, integrate Java classes with their own JPython classes. JPython compiles directly to Java bytecode, generating Java .class files, which can be used to create applets.
By the way, JPython programmers also refer to Non-Java Python as CPython in order to distinguish Python's Java Implementation from Python's C implementation. Conclusion Now, just imagine projects that require several layers of application design. Do you think that these projects'leaders have some kind of problem to scale up their applications? If you've been in a situation like that, have you ever thought about using the same language for all your needs? Are you going to have a programmer coding in JavaScript? (That language doesn't support exception handling.) Say that you need to create some Java routines, using Servlets, for the back end. What if this programmer doesn't know Java? Are you going to explain Java to him, or are you going to hire a Java programmer? Nowadays, technology and projects are moving too fast. You don't have time to teach new technologies to the people who are coding your applications. This is one more reason to stick with Python. You have the flexibility to play in all bases and do almost everything using the same language. I am sure you are satisfied now that you know the reasons why Python is a fantastic language. What are you waiting for? I strongly encourage you to use Python now. For more information about Python versus other languages, check out the following URL: http://www.python.org/doc/Comparisons.html.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 1. Introduction > Patches and Bugs List
CONTINUE >
bug fixes
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 1. Introduction > PSA and the Python Consortium
CONTINUE >
Several Special Interest Groups (SIGs), hosted by PSA, are currently studying and developing special topics of Python, such as XML Processing, String Processing, Python in Education, Distributed Objects, and many other important topics. To find out what newest groups are being formed and to participate in the discussions that are conducted in their mailing lists, take a look at http://www.python.org/sigs/. Much of Python's real work takes place on Special Interest Group mailing lists. Behind the PSA, a group of companies and individuals helps to propagate the Python voice. They work together, creating conferences and keeping their Web site up-to-date. If you want to be part of the PSA, get more details at http://www.python.org/psa/. After you become a member of the PSA, you are eligible to have an account on the Web site http://starship.python.net. Today, this site is filled with information provided by many Python developers from all around the world. On Oct 25, 1999, the Python Consortium was publicly announced and officially began its mission "to ensure Python's continued support and development."
The membership fees that are received by the Consortium members support the development of Python and JPython. Many organizations have already registered as part of the Consortium (for more information, see http://www.python.org/consortium/). The Corporation for National Research Initiatives (CNRI) is a nonprofit organization that hosts the Python Consortium. Check out its Web site at http://www.cnri.reston.va.us/. Even with his transition to PythonLabs, Guido van Rossum remains the Technical Director of the Python Consortium, and BeOpen.com continues to be just a member. Support and Help Python has a Usenet newsgroup called comp.lang.python. This newsgroup is an excellent source of Python information and support. The guys who really know the language always hang out there. One of the best ways to keep yourself up-to-date to the Python world is to sign up for the Python general mailing lists and to always check the newsgroup for some information that might be helpful for you. Go to http://www.python.org/psa/MailingLists.html and look for the list that provides the level of information that you need. At this time, there are four main mailing lists: Tutor is a list for beginners who have basic knowledge and need simple and straight answers. JPython is a list that openly discusses the Python implementation for Java. Announcements is a list that doesn't have huge traffic. The objective of this list is just to publish important notices to the Python community. An open discussion mailing list generates an average of 100 daily messages and covers everything related to general Python discussion topics. Python Conferences and Workshops The Python community has organized many workshops and conferences to discuss Python hot topics. You can have access to the materials that were used for the presentations, and you can also download many technical documents provided by the people who have participated in the conferences and workshops. For more details about the latest events and upcoming ones, check out the Web page at
http://www.python.org/workshops/.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 1. Introduction > Summary
CONTINUE >
Summary
Python is an interpreted, high-level programming language, pure object-oriented and powerful serverside scripting language for the Web. It is an open source project that doesn't have any copylefts or copyrights involved in its license agreement. You should consider moving to Python because it is simple to get support from the Python community; it is fast to learn and code it; it offers object-oriented programming support; and it provides a readable, reusable, and portable coding language. The main technical features that distinguish Python from the other languages are as follows:
q
Automatic memory management Exception handling management Rich core library Web scripting support and data handling Rich built-in elements Clear syntax and useful lexical elements Embeddable and Extendable language Objects Distribution support Databases support GUI applications support Introspection Easily integrated to third-party projects.
Python runs on many platforms, such as Microsoft Windows, Linux, and Macintosh. The source code and the documentation are freely downloadable. It is also available for downloading the binaries for some systems. Python is always compared against other languages and, usually, it wins. Python has an implementation in Java called JPython. Two institutions have guided the Python community along the last few years: the Python Software Activity (PSA) and The Python Consortium. The PSA took the responsibility of creating Python conferences and workshops and keeping the Python official Web site up and running, whereas The Python Consortium supported the development of Python and JPython. Today, the future of these two institutions is a little uncertain because Guido and his whole development team have moved to BeOpen.com to support PythonLabs.com. The Python community has been doing a great job by providing help to new Python aficionados. Most of this help is provided through the mailing lists, newsgroups, bug lists, and other available forms of support. By the way, Python has nothing to do with those legless reptiles. It was named after the British comedy troupe Monty Python.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark 2002, O'Reilly & Associates, Inc. CONTINUE >
CONTINUE >
Web Development > Python Developer's Handbook > 2. Language Review > Language Review
CONTINUE >
Language Review
Some people say that Python is a magic language because it enables you to do almost everything with a minimum amount of code. The coding speed depends only on your effort to acquire the required knowledge to decide which commands you should use. Different from other languages, Python doesn't sell the idea of being able to code one task in many ways. The reason for that is because there is only one dialect of Python. Therefore, the core language doesn't provide a huge number of grammar styles and definitions. Consequently, you can keep the entire vocabulary in your mind without too much effort. After spending some time studying Python, you can easily master the whole set of instructions that shapes the core language. As Python doesn't have any hard-to-remember commands, the language is very comfortable and simple. Most of the work that you have to do is identify the right module for your needs. By the way, Python's standard library of modules is very complete and well documented. This chapter will guide you across the lines of code that are required to reach the stardom. Among other things, handling control statements and performing files management will become easy tasks for you. Later, in the following chapters, you will learn how to go through each important Python module and understand what it does and how useful it can be for you. Now, let's roll up our sleeves and start working.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark 2002, O'Reilly & Associates, Inc. CONTINUE >
Web Development > Python Developer's Handbook > 2. Language Review > The Shell Environment
CONTINUE >
$ python
c:\> python
Note that in both cases, you just need to type the word python; the rest is part of the shell prompt. The Python for Windows installation also provides access to the command line interpreter by clicking its icon on the Start menu (see Figure 2.1).
Figure 2.1. By clicking on the Python (command line) icon, you gain access to the shell environment.
After the command line interpreter is loaded (see Figure 2.2), you can start coding your own programs.
Figure 2.2. Python's command line interface is now ready to use.
Instead of using the command line interpreter, you can also use a graphical user interface called IDLE (see Figure 2.3).
Figure 2.3. IDLE is Python's GUI interpreter.
Note See Chapter 16, "Development Environment," for details about using IDLE.
As you can see by looking at the coding area in both Figures 2.2 and 2.3, the interpreter's primary prompt is a >>>. Let's start interacting with Python by running a variation of the standard "hello world" program.
The previous example demonstrates that the screen is the standard output device for commands that are typed in the interpreter's prompt. Next, another example is demonstrated. Note that the first command doesn't print anything because it is just an assignment operation. The result of the operation is passed to and stored at the informed variable. On the other hand, the second command has its output redirected to the standard output, which enables you to see the result of the operation.
Python's syntax automatically indicates when a statement requires a subblock. The interpreter's secondary prompt means that the next line is a continuation from the current line and not a new line. In some cases, when you finish entering a multiline statement, you need to type ENTER at the beginning of the first line located after the end of the code block. By doing so, you will return to the primary prompt. Four basic situations that use a secondary prompt are as follows:
q
>>> print ("I am a lumberjack " + \ "and I am OK.") I am a lumberjack and I am OK. >>> a = { 'song': 'lumberjack' }
Tip If you need to quit the interpreter while working on UNIX or MS Windows systems, press CTRL+D or CTRL+Z, respectively.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 2. Language Review > Programs
CONTINUE >
Programs
Until now, all the examples were written directly in the interpreter environment. However, most Python programs are executed as external scripts, being loaded from files. You can write your own Python scripts by using any text editor of your choice. Remember to always save your files using the .py extension. As with any other UNIX scripting language, Python scripts (for UNIX) need a special handling. First, you need to put a "shebang" in the first line of the script. This line declares the location of Python's interpreter in your system. For example
#!/usr/local/bin/python
Note that this example works only if Python was installed under the given mounting point. Most Linux systems have Python installed under /usr by default, so the preceding example will not work. Today, the following line of code seems to be more common, and does not depend on where Python is installed:
#!/usr/bin/env python
If you are running your scripts on an MS Windows environment, you can keep this line of code for portability purposes because the literal # is only used to identify comment lines that are ignored by the interpreter, so it will cause no harm to your programs. Tip The "shebang" line is only meaningful when you work on a UNIX system.
If you don't know where Python is located on your UNIX system, use the following command:
$ whereis python
Also, remember to set the permissions on your script to 755 in order to let every user be able to execute it.
$ chmod +x scriptname.py
or
As you cannot directly execute Python scripts in the MS Windows systems through the command line, you have two options: Either double-click the file using Windows Explorer or call the interpreter, passing the filename as an argument. For example,
c:\>python scriptname.py
Another way to call the interpreter on Windows systems is by typing start scriptname.py at the shell prompt. This command will find and execute the program associated with the extension .py. If you want to open the interpreter after executing a program, use the -i argument when calling the script. The interpreter will run your script, and after it executes all the commands, it will open its command-line interface for you. Here's how to call the script with a command-line option:
c:\python -i scriptname.py
Otherwise, after the script finishes its execution, it will automatically close the interpreter. After spending some time creating Python programs, you might find some .pyc files in the same directory in which you are saving your .py scripts. See Chapter 17, "Development Tools," to know more about this other file extension. Indentation Python delimits code blocks by using indentation. There is no concept of {}s or Begin/Ends as in other languages. When you indent a block of code, you define the way the statements are grouped. It also reduces errors due to bad indentation. For instance, the following C or Perl code looks like a single if statement, but the second statement is always executed:
Python doesn't suffer from this problem because indentation defines block structure. Another great aspect of this implementation is that you can reduce the size of your code while using indentation instead of conventional block delimiters. Tip Keep in mind that tabs are internally converted to spaces (1 tab = 8 spaces), and blank lines are ignored when part of scripts.
I suggest you write one statement per line, using a newline (ENTER) to terminate each line. If you decide to have more than one statement in the same line, you need to separate them by using semicolons, as shown in the following:
Remember that you must put a backslash \ at the end of lines that need to be broken into two lines:
Lexical Analysis It is unnecessary to declare the type of a variable in Python programs. The same variable name might have different types at different occasions because it is re-initialized every time a value gets assigned to it, as illustrated in the following:
>>> x = "Albatross!!" >>> print x Albatross!! >>> x = 123 >>> print x 123
You can assign any object type to a variable (for example, functions, classes, and modules). The following example shows how you can create a variable that references the round() function object:
You don't have to worry about deallocating variables in Python. Python objects are collected whenever they become unreachable because Python does reference counting. This means that as long as there is a reference to an object, the object isn't collected. When you delete a reference to an object, its reference counting goes down by one, and when the count has dropped to 0, it is eligible for garbage collection. Note that under CPython, objects are deallocated as soon as the reference count reaches 0. The problem with reference counting is that you can create circular references, such as the following:
>>> >>> [1, >>> >>> [1, >>> [4, >>> >>>
a.append(b) a 2, 3, [4, 5, 6]] b.append(a) a 2, 3, [4, 5, 6, []]] b 5, 6, [1, 2, 3, []]] del a del b
Now, you can never refer to variables a and b, nor to their contents again, and because each one of them is still referenced by the other list, they cannot be collected, either. Note that recursion is indicated by the [] element. I know that it is fairly easy to fall into this trap, and although some work is being done to cure this problem, I strongly suggest that you avoid recursive constructs. As you might notice, del removes the reference to the object, which could cause it to be deallocated if its reference count reaches 0. You can monitor the reference counting of an object by using the sys.getrefcount() function:
Note that you can break the circular reference if you insert the following lines between the appends and dels:
Actually, we are just breaking the references by removing the [] entries from the lists. Note that the release 2.0 of Python makes sure that deleting objects is safe even for deeply nested data structures. The Python interpreter is now using a new mechanism to collect unused objects. From time to time, this mechanism performs a cycle detection algorithm that searches for inaccessible cycles and deletes the participating objects. This process has been named Garbage Collection of Cycles.
There are a couple of parameters of the garbage collection that you can manipulate. The module gc provides functions that helps you out with that. Of course, you always have the option to disable this feature. To do so, simply specify the argument " -without-cycle-gc " when running the Python configure script. Reserved Words Python has reserved a group of words for its own use. Those words have specific meanings that cannot be changed. You cannot use these words as identifiers in your code.
"and, assert, break, class, continue, def, del, elif, else, except, exec, finally, for, from, global, if, import, in, is, lambda, not, or, pass, print, raise, return, try, while"
Identifiers Python identifiers are any objects created by programmers (such as variables, classes, and so on). Identifiers can be named using any of the following characters: A-Z, a-z, 0-9, and _. However, they can't start with a digit. You must write your code carefully because Python identifiers are case sensitive. The special characters: $, %, and @, aren't allowed to be part of an identifier's name. Besides that, $ and @ can be used only in a program, inside quoted strings. The % character may be used in a program because it is the mod operator.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
counting reference creating line breaks scripts 2nd 3rd 4th 5th deallocating variables declaring variables del command dollar sign ($) identifier names elements [] entries [ ] executing scripts from Windows finding Python in UNIX functions round() sys getrefcount() garbage collection Garbage Collection of Cycles identifiers interpreters opening after executing programs launching interpreters after executing programs scripts from Windows line breaks adding lines blank, in scripts separating statements on shebang monitoring reference counting, objects naming identifiers numbers starting identifiers with objects assigning to variables
monitoring reference counting unused collecting objects opening interpreters after executing programs scripts from Windows percent sign (%) identifier names permissions setting on scripts programs opening interpreters after executing recursion [ ] element reference counting references circular round() function running interpreters after executing programs scripts from Windows scripts executing from Windows lines in setting permissions tabs in writing 2nd 3rd 4th 5th searching Python in UNIX semicolons ( ) separating statements on same line sensitivity case identifiers separating lines statements on same line setting permissions on scripts shebang line software opening interpreters after executing start scriptname.py command statements
separating on same line sys getrefcount() function tabs in scripts UNIX finding Python shebang line unused objects collecting variables assigning objects to deallocating declaring variables whereis python command Windows executing scripts from writing scripts 2nd 3rd 4th 5th
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 2. Language Review > Built-In Data Types
CONTINUE >
x = 1 x print x x = None x
As you could see, nothing was returned. However, if you try to print this value, the print method of the object will specially handle the None value by returning a None result. This is shown in the following:
Numbers
Python provides the following numeric data types: integer, floating-point, hexadecimal (base 16), and octal (base 8). Some examples of these data types are 43, 1.5, 0xB3, and 045, respectively. Tip Hexadecimal numbers must always be preceded by 0x, and octal numbers must be preceded by 0.
A very important detail is the fact that Python truncates integer divisions:
>>> 3/2 1
If you really want the decimals, you have two options. Either you pass a converted number to the division function, or you put a decimal point in your number, as illustrated here:
x = 3 float(x)/2 x 3.0/2
Python supports long integerswith unlimited size. To let Python know that it should handle an integer as a long integer, you need to put an L at the end of the number:
>>> 2**100 Traceback (innermost last): File "<stdin>", line 1, in ? OverflowError: integer pow()
Chapter 4, "Exception Handling," teaches you how to interpret this exception message. Python also handles complex numbers in the format (real part + imaginary part):
Strings Python considers a string as a sequence of characters. Therefore, every time you use, for example, the string "Parrot", internally Python handles it as the sequence ["P", "a", "r", "r", "o", "t"]. The first indexer value is always the number zero. Hence, to have access to the letter P, you need to say "Parrot"[0] and to access the letter a, you need to say "Parrot"[1]. Using the same concept, we can get access to all the other elements. The following is an example of string operators:
>>> "dead parrot " + "sketch" "dead parrot sketch" >>> "parrot " * 2 "parrot parrot" >>> "parrot"[1] "a" >>> "parrot"[-1] "t" >>> "parrot"[1:3] "ar"
When slicing, it isn't necessary to include both first and last elements. Whenever you omit one of the elements, it is assumed that you want everything in that direction. Note that the second argument is always a positional reference.
"par"
Always remember that assigning z = x doesn't make a copy of the object x. Instead, it creates a new reference for that object (as you already saw in the earlier round example). If you have to create a copy of a sequence named x, you need to type:
>>> z = x[:]
The variable z will identify the middle of the variable x, and it will be initialized with everything from the left direction plus everything from the right direction. Note that since Python 1.5, id(s) == id(s[:]) for strings because of string interning. Strings cannot be modified after creation. It isn't possible to assign a value to a substring because strings are immutable. See the error message in the next example:
>>> t = "pxrrot" >>> t[1:2] = "a" Traceback (innermost last): File "<stdin>", line 1, in ? TypeError: object doesn't support slice assignment
For example
Let me show you other useful operations that you can do with strings:
>>> len("parrot") 6 >>> "parrot" < "sketch" 1 >>> "t" in "parrot" 1 >>> "\n, \0, \x" "\012, \000, \\x"
# Get its length # Compare one string against another. # This logical test needs a char left operand # Use escape codes
Table 2.1. Escape Codes Supported by Python Strings Escape Code \\ \' \" \b \e \0 \n \v \t \r \f \0nn \xnn Description backslash single quote double quote backspace escape null linefeed, also known as \012 vertical tab horizontal tab carriage return form feed octal value, the nn domain is: 0..7 hexa value, the nn domain is: 0..9, A..F, a..f
You can use either single quotes or double quotes. They are both interpreted the same way. Both strings 'Spam' and "Spam" are basically the same thing. Python also accepts triple quotes for remarks that span across several lines:
>>> t = """I am a lumberjack and I am OK""" >>> print t I am a lumberjack and I am OK >>> t "I am a lumberjack\ 012and I am OK"
Note that the escape code \012 becomes part of the string. If you need to create strings with the / (slash literal), you must use raw strings. Raw strings are identified by the letter r right before the first quote, as shown in the following:
There is one more thing that I think you should know about strings. The enclosing backticks `` tell the interpreter to understand that the enclosed object is of string data type:
Note Python doesn't treat the contents of back quotes as commands to execute, as do Perl and sh.
Prior to version 2.0, you had to rely on the string module to manipulate your string objects because the string-manipulation functionality was in the string module. With this new release, the methods were pushed to the string type. Note that old string module was not removed from the distribution because it is still necessary for backwards compatibility. The following example shows how to call a method from a string object.
Note that 'Python '.join('World') is equivalent to the old string module: string.join("World", "Python ") Besides the methods that were inherited from the string module, two new methods were added: startswith() and endswith().
and
Unicode Support
Unicode is a new immutable string data type supported by Python 2.0. Basically, it can represent characters using 16-bit numbers, instead of the 8-bit numbers used by the ASCII standard, which means that Unicode strings can support up to 65,536 distinct characters. Note that when combining an 8-bit string and an Unicode string, the resulting string is an Unicode string. In order to write a Unicode string in Python, you need to use the notation u"string". If you need to write arbitrary Unicode characters, you can use the new escape sequence, \uHHHH, where HHHH is a 4digit hexadecimal number from 0000 to FFFF. Note that you can also use the existing \xHHHH escape sequence. Another option is to use octal escapes whenever you need to write characters up to U+01FF (represented by \777).
True and False Logical Values Falsity is represented by zeros, empty structures, or the value None (for example, 0, [], {}, (), None). Logical Truth is represented by results different from zero and non-empty structures (for example, 1, [2], (1,2,3), "abc"). The following if statement checks whether the variable t has any value; in this case, the statement returns true, allowing the block contents to be executed:
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
calling methods from string objects characters codes escape comparisons numbers complex numbers handling copying objects creating strings, slash literal (/) data types immutable None decimals in numbers double quotes ( ) strings duplicating objects endswith() method equations numbers in error messages assigning values to substrings handling long integers escape code 2nd 3rd 4th 5th 6th 7th 8th 9th 10th escape codes floating-point numbers functions numbers in handling complex numbers long integers hexadecimal numbers immutable data types indexer values strings integers division of, truncations long handling long integers handling masking
numbers in messages error assigning values to substrings handling long integers methods calling from string objects endswith() print startswith() modules string None data types null value assigning to variables (double quotes) strings (triple quotes);strings (single quote) strings objects copying string calling methods octal numbers operations binary numbers in print method quotes strings 2nd raw strings creating strings with slash literal (/) shifting numbers in single quotes ( ) strings slash literal (/) creating strings slicing strings startswith() method string modules string objects methods
calling strings 2nd 3rd 4th strings substrings assigning values support Unicode 2nd triple quotes ( )strings truncations division of integers Unicode support 2nd values assigning to substrings indexer strings null assigning to variables
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 2. Language Review > Operators
CONTINUE >
Operators
Next, I list the available Python operators in their precedence order. I also provide some specific details about some of them. 1. (), [], {} 2. `object` 3. object[i], object[l:r], object.attribute, function() The . (dot) operator is used to access attributes and methods of a variable (object). In the following example, the dot enables the object t to access its method append.
4. +x, -x, ~x These are bitwise operators. 5. x**y 6. x*y, x/y, x%y The % (modulo) operator lets you know whether a number is divisible by another number. For example, if a % b == 0, a is divisible by b. 7. x+y, x-y
8. x<<y, x>>y These operators provide shifting operations. The << operator ensures left shifting (at bit level), and the >> operator ensures right shifting (at bit level).
9. x & y The bitwise AND operator 10. x ^ y The bitwise XOR (exclusive OR) operator 11. x | y The bitwise OR operator 12. <, <=, >, >=, ==, !=, <>, is, is not, in, not in The operators in and not in work only with lists. Another aspect of this group is that there's an important difference between the == operator and the = assigning symbol. is checks whether two variables refer to the same object. On the other hand, is not checks whether two variables don't refer to the same object. The == operator ensures equality testing, whereas = assigns a value to a variable. Tip Keep in mind that x = y doesn't create a new copy of y. Instead, it makes a reference to it. However, if later you define x=x+1, a new reference for x is created, and then they become different because the operator has created a new object.
Note that x.append(5) doesn't create a new reference to x because x changes itself without using a = operator.
13. not 14. and 15. or, lambda args:expr As a good programmer, you need to know that logical operations can also be emulated by using if statements. Note that the return values are not limited to zeros and ones. The operation a and b can be written as the following:
#If a is false
#If a is true
Augmented Assignment Starting with Python 2.0, the language also implements a full set of augmented assignment operators. That includes: +=, -=, *=, /=, %=, **=, &=, |=, ^=, =, and = For example, instead of saying x = x+1, you can choose to say x += 1
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
modulo (%) operator not in operator objects copying operator operators augmented assignment OR operator right shifting shifting statements if XOR (exclusive OR) operator
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 2. Language Review > Expressions
CONTINUE >
Expressions
Python operators support a wide range of expressions, such as
x,y,z = z-x, y*z, x+y # Parallel assignment: example 1 x,y,z = 5,4,3 # Parallel assignment: example 2 a,b = b,a # Switching assignments a = b = c = 10 # Multiple assignments string.atof(s) # Functions support 20 < x < 40 # Multiple range testing
Built-In Functions The following functions are always available when you load the Python interpreter. You don't need to import them because they are already part of the __builtin__ module, which is always imported when you launch Python.
apply()
It executes a given function, passing the arguments provided. basic syntax: apply(function, (tuple of positional arguments) [, dictionary of keywords arguments])
Note that starting at Python 1.6, the functionality of apply is now available with normal function calling, such as
>>> args = (6000,) >>> kwargs = { 'employee':'John', 'id':13} >>> raise_salary(*args, **kwargs)
coerce()
coerce is used to try to convert the two given arguments x and y to the same type, returning them as a tuple. basic syntax: coerce( x, y )
filter()
It creates a new list by taking each element of list for which function evaluates to true. basic syntax: filter( function, list )
globals()
input()
It provides an input interface for the user. Only numbers are accepted. basic syntax: input( [prompt] )
a = input("Please, type a number greater than 5: ") if a<5: print "a is not greater than 5"
locals()
It applies a function to each element of list, producing another list. If function is set to None and multiple lists are provided, a tuple matrix is generated in the format of a list. basic syntax: map( function, list )
>>> lst = map(None, [1,2,3,4], [1,2,3,4,5,6]) >>> lst [(1, 1), (2, 2), (3, 3), (4, 4), (None, 5), (None, 6)]
open()
It opens a file. (See the section "File Handling" for details.) basic syntax: open( filename [,mode [,bufsize]] )
pow()
It returns x**y or (x**y) % z, depending on the number of arguments that are transported.
It reads from standard input (sys.stdin), returning the read data as a string. prompt is an optional text that can be displayed in the screen. basic syntax: raw_input( [prompt] )
reduce()
It applies a function cumulatively to the items in sequence (implied loop), returning a single value. initializer is an optional starting value. basic syntax: reduce( function, sequence [,initializer] )
def reduce(func, list): ret = list[0] for x in list[1:]: ret = func(ret, x) return ret
__import__()
This is a function invoked by the import statement. To import a module, you just need to inform the module name. basic syntax: __import__( module_name [,globals() [, locals() [,from list]]] )
reload()
It reloads an already imported module. Internally, it calls the __import__ function. basic syntax: reload( module ) Sequence Functions The next set is built-in functions that deal with sequences.
range()
It returns a list of numbers according to the transported information. basic syntax: variable = range( [initial_value,] final_value-1 [, step] )
It is similar to range(), but it doesn't assign the returned list to a variable, Therefore, it doesn't use as much memory, so you won't run out of memory by typing xrange(2000000000), for instance. basic syntax: xrange( [initial_value,] final_value-1 [, step] ) See the section "Data Structures" for details.
len()
min()
zip()
It returns a list of tuples where each tuple contains the i-th element from each of the given sequences. This function generates a resulting list whose length is exactly the same as of the shortest given sequence. Note that, on the other hand, the function map(None, sequence1, sequence2, ) pads the resulting list with None when the sequences don't have the same length. basic syntax: zip( sequence1, sequence 2, sequence3, ) Object Manipulation
The next set is built-in functions that deal with object handling.
setattr()
It sets a new value for object.name basic syntax: setattr( object, name, value )
getattr()
It returns the attribute from object. This command is equivalent to object.attribute. basic syntax: getattr( object, attribute )
hasattr()
It returns 1 if object has attribute, 0 if it doesn't. basic syntax: hasattr( object, attribute )
delattr()
It deletes the attribute from object. This command is equivalent to del object.attribute. basic syntax: delattr( object, attribute )
type()
dir()
It returns a list of attribute names from the active namespace. object can be anything (a variable, a module, a class, and so on). basic syntax: dir( [object] )
callable()
It returns the system unique identifier of object. basic syntax: id( object )
vars()
It returns the symbol table of object or a dictionary from the local namespace. basic syntax: vars( [object] ) Mathematical/Logical Functions The next set is built-in functions that deal with mathematical and logical operations.
abs()
cmp()
It returns -1 when x<y; 0 when x==y, 1 when x>y basic syntax: cmp(x,y)
round()
It rounds number to the given number of decimals. Note that the provided number is rounded to an integer by default. basic syntax: round( number [,decimals] )
divmod()
It returns a tuple (quotient, remainder), resulting in the expression dividend/divisor. basic syntax: divmod( dividend, divisor )
Code Functions The next set is built-in functions that deal with Python bytecode manipulation.
eval()
It evaluates the compiled code string object as if it were Python code, and returns the result. globals and locals define the namespaces for the operation. Note that eval can evaluate
expressions onlynot arbitrary statements. Therefore, eval('import string') won't work. basic syntax: eval( string [,globals [,locals]] )
exec()
exec is a statement that executes a string containing Python code. globals and locals define the namespaces for the operation. basic syntax: exec string [in globals [,locals]]
execfile()
It executes the statements included in the file provided. globals and locals define the namespaces for the operation. basic syntax: execfile( file [,globals[,locals]] )
>>> execfile("c:\\python\program2.py")
You can redefine the global and the local namespaces for these functions by creating dictionaries, just like the next example shows. If you omit the values, the current environment namespace is always used.
compile()
It compiles a code object ( string ) that optionally might be located in a file. The type value depends on the following: if string is a sequence of statements, type is "exec"; if string is a single expression, type is "eval"; and if string is an executable statement, type is "single". basic syntax: compile( string, file, type )
a = "for i in range(0,10): print i," b = compile(a, "", "exec") exec b 2 3 4 5 6 7 8 9 a = "123 * 2" c = compile(a, "", "eval") d = eval(c) d
Tip If you need to evaluate or execute the same code many times in your application, the application will get more optimized if you compile all the source code first.
Type Conversion The next set is built-in functions that deal with data type conversion.
int()
It converts object to a long integer. basic syntax: long( object ) As of Python 2.0, the functions int() and long() have an optional base argument, which can be used when the first argument is a string. Note that if you try to use this second argument with a value that is not a string, you get a TypeError exception message. The following examples demonstrate what happens when we use this argument: int('450', 10) returns 450, and int('25', 16) returns 37.
float()
It creates a complex number in the format ( real number + imaginary number) basic syntax: complex( real [,imaginary] )
str()
It returns the printable representation of object. It returns the same value that a " print object " statement does. basic syntax: str( object )
repr()
It is equivalent to the enclosing backticks ``. It returns an expression that can be evaluated. basic syntax: repr( object ) You can use either repr() or `` to get the representation of an escape character.
tuple()
This function takes an 8-bit string and creates a Unicode string. basic syntax: unicode( string [, encoding] [, errors] ) encoding and errors are some additional arguments that you can also provide to the function. The first one is a string that names the encoding to use. errors defines what to do when an invalid character is used for the current encoding. You have three options for values here: strict causes an exception to be raised on any encoding error, ignore simply ignores any errors, and replace replaces the invalid character with the official replacement character U+FFFD whenever it finds any problem.
unichr()
This function returns a 1-length Unicode string containing the given character. basic syntax: unichr( character )
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
sequence syntax unichr() zip() unicode() syntax zip() handling objects functions 2nd int() function base argument logical functions mathematical functions objects handling functions 2nd sequence functions syntax functions abs() apply() callable() chr() cmp() coerce() compile() complex() delattr() dir() divmod() eval() exec() execfile() filter() float() getattr() globals() hasattr() hash() hex() id() import () input() int() len()
list() locals() long() map() min() oct() open() ord() pow() range() raw input() reduce() reload() repr() round() sequence() setattr() str() tuple() type() unichr() unicode() vars() xrange() zip() tuples zip() function syntax type conversion functions 2nd unichr() function syntax unicode() function syntax zip() function syntax
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 2. Language Review > Control Statements
CONTINUE >
Control Statements
Python implements all the necessary types of control statements that your program might require. The syntax provided by Python's if, for, and while statements should be enough for your needs. Tip Remember to type a colon at the end of each line where you enter a statement declaration.
1: 2: 3: 4: 5: 6: 7: 8: 9:
if <condition>: <statements> [elif <condition>: <statements>] [elif <condition>: pass] [else: <statements>]
Note that both elif and else clauses are optional. As you can see in lines 3 through 7, it is only necessary to use elif when you need to handle multiple cases. That is exactly how you implement the switch/case statements from other languages. Line 6 introduces you to an empty clause that does nothing. It is called pass. for
The for statement implements loops within a sequence (list). Each element in the sequence assigns its value to variable on its turn. The general syntax is as follows:
The else clause is only executed when the for statement isn't executed at all, or after the last loop has been executed. In other words, the else statement is always executed unless the break statement is executed inside the loop. Let's see some examples:
>>> for n in [1,2,3,4,5]: print n, 1, 2, 3, 4, 5 >>> t = [(1,2),(2,4),(3,6)] >>> for t1, t2 in t: print t1, t2 1 2 2 4 3 6
while The while statement implements a loop that executes the statements while the condition returns true.
The else clause is only executed when the while statement isn't executed at all, or after the last loop has been executed. In other words, the else statement is always executed unless the break statement is executed inside the loop. The following example demonstrates the use of the while statement:
The next example implements an infinite loop because the pass statement does nothing and the condition will always be true.
break/continue Next are two commands that can be used inside for and while types of loop.
break
The break clause exits a loop statement without executing the else clause.
1 2
continue
The continue clause skips the rest of the loop block, jumping all the way back to the loop top.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 2. Language Review > Data Structures
CONTINUE >
Data Structures
Python implements a variety of data structures, such as lists, tuples, ranges, and dictionaries (also known as hash tables). Lists Lists are mutable sequences of objects indexed by natural numbers that can be changed after they are created. Lists are very flexible and easy to create. They are always enclosed in brackets:
A list uses the same operators that strings use. For example, you need to use slice notation to grab a range of elements from a list.
>>> lst = [1, "ni!", [1, 2, 3, 4, "Albatross!!", 3]] >>> lst[1] "ni!"
To grab elements from lists that are located inside other lists, you need to use a pair of brackets to represent each list. Check out the next couple of examples.
>>> lst = [1, "ni!", [1, 2, 3, 4, "Albatross!!", 3]] >>> lst[2][4] "Albatross!!" >>> lst[2][4][5] "r"
>>> lst = ["p", "a", "r", "r", "o", "t"] >>> lst.index("o") 4
>>> lst = ["p", "a", "r", "r", "o", "t"] >>> lst[1] = "aaaaaaaaaaaaa" >>> lst ["p", "aaaaaaaaaaaaa", "r", "r", "o", "t"]
>>> lst = ["p", "a", "r", "r", "o", "t"] >>> lst[1:4] = ["aaaaaaaaaaaaa", "rrr", "rrrr"] >>> lst ["p", "aaaaaaaaaaaaa", "rrr", "rrrr", "o", "t"]
Inserting Values
>>> lst = ["p", "a", "r", "r", "o", "t"] >>> lst[6:] = [" ", "s", "k", "e", "t", "c", "h"] ['p', 'a', 'r', 'r', 'o', 't', '', 's', 'k', 'e', 't', 'c', 'h']
If the list was longer than 6 elements, the statement would overwrite a portion of the list. Note that you can also insert a value in this list with
Deleting a Value
>>> lst = ["p", "a", "r", "r", "o", "t"] >>> del lst[-1] >>> lst ["p", "a", "r", "r", "o"] >>> del lst[0:2] ["r", "r", "o"]
>>> lst = [10,20,30,"inquisition","lumberjack"] >>> text = "" >>> for element in lst: text = text + `element` # enables the concatenation of any object print text 10 1020 102030 102030'inquisition' 102030'inquisition''lumberjack'
List Comprehension
Starting with release 2.0, there is a new notation to create lists whose elements are computed from another list (or lists). The method is called List Comprehension, and it adopts the following format:
[ expression for expression1 in sequence1 [for expression2 in sequence2] [ for expressionN in sequenceN] [if condition] ]
All forin clauses are evaluated and iterated from left to right. That means that the resulting list is a cartesian product of the given sequences. For example, if you have three lists of length 5, the output list has 125 elements. The if clause is optional, but when present, it can limit the number of pairs that will become part of the resulting list by adding pairs to the resulting list only when the result condition of the if statement evaluates to true. Check the following example:
letters = 'py' numbers = (1.52, 1.6, 2.0) >>> [ (l,n) for l in letters for n in numbers] [('p', 1.52), ('p', 1.6), ('p', 2.0), ('y', 1.52), ('y', 1.6), ('y', 2.0)]
This new concept is more efficient than a for loop with an if statement along with a list.append() function call. Built-In Methods To list all the built-in methods of a list, go to the interpreter and type dir([]). Let's practice the methods that you have found, and see what happens to our list lst.
lst = [0, 1, 2] lst.append(5) lst 1, 2, 5] lst.append((5, 6)) lst 1, 2, 5, (5, 6)] lst.pop() 6)
>>> [0, >>> >>> [0, >>> 7 >>> [0, >>> >>> [5, >>> >>> [0, >>> >>> [0, >>> 2 >>> 4 >>> >>> [0,
lst 1, 2, 5] lst.insert(2,7) lst 1, 7, 2, 5] lst.pop(2) lst 1, 2, 5] lst.reverse() lst 2, 1, 0] lst.sort() lst 1, 2, 5] lst.extend([3, 4, 5]) lst 1, 2, 5, 3, 4, 5] lst.count(5) # counts
lst.index(3) # returns the associated index of element 3. lst.remove(2) # removes the element number 2 (not the index!!!) lst 1, 5, 3, 4, 5]
Note that up to release 1.5.2, whenever you used lst.append (1,2), a tuple (1,2) would be appended to the list lst. Now, with release 2.0, when you do that, you get an TypeError exception followed by a message like " append requires exactly 1 argument; 2 given ". Don't panic! To fix that, you just need to add an extra pair of parenthesis, like this: lst.append ((1,2)). Ranges A range is an actual list of integers. The built-in function range() provides this data structure.
When you provide a third argument to the range() function, you specify the interval that you want to exist between the list elements.
The xrange() function computes the values only when they are accessed. This function returns an XrangeType object, instead of storing a large list of numbers in a variable.
The previous example also works with the range() function, although it will store the whole list in memory. It is possible to assign a reference to the return value of the xrange() function to a variable, as you will see next. Note that we are not storing the values, only a reference to the function.
However, you can convert this reference later into a real list by using the tolist() method.
Tuples A tuple is a sequence of immutable Python objects. The general syntax of a tuple is as follows:
It looks like a list without the brackets. Note in the following examples that parentheses are optional.
>>> t = (1,) >>> print t (1,) >>> t = 1, >>> print t (1,) >>> t = () >>> print t () >>> t = (1,2,3) >>> print t (1,2,3) >>> t = 1,2,3 >>> print t (1,2,3)
Note that in the previous example, it is necessary to use the comma when defining a length-1 tuple.
Otherwise, the variable being created wouldn't be defined as of type tuple. Instead, the interpreter would think that you wanted to assign a numeric value to the variable. A tuple really looks like a list. The difference between tuples and lists is that tuples are immutable. You can bypass this rule if you bind a new structure to the old tuple variable.
You will see, later in this chapter, that you need to use tuples whenever you need to return more than one value from a function.
>>> Def tuplefunction(): return 10, 20, 30 >>> x, y, z = tuplefunction() >>> print x, y, z 10 20 30
Dictionaries (hash tables) Dictionaries illustrate the only mapping type of Python. They represent finite sets of objects indexed by nearly arbitrary values. I say nearly because dictionary keys cannot be variables of mutable type, which are compared by value rather than by object identity. Python dictionaries are also known as associative arrays or hash tables. The general syntax
of a dictionary is as follows:
Dictionaries are always enclosed in braces. They associate key elements with value elementskeys and values are displayed separated by a colon. The values of a dictionary can be of any type, but the keys must be of an immutable data type (such as strings, numbers, or tuples). Dictionary keys have no natural order and are always listed in arbitrary order because it uses a hash technique to implement a fast lookup. Let's focus now on the operations that we can implement with dictionaries. First, let's create a simple dictionary.
>>> dic["fish"] # value lookup "tuna" >>> dic["animal"] # raises a KeyError exception Traceback (innermost last): File "<stdin>", line 1, in ? KeyError: animal >>> del dic["fish"] # deletes the key fish >>> print dic {'bird': 'parrot', 'dino': 't-rex'} >>> dic["dino"] = "brontosaur" # updates an entry >>> dic["parrot age"] = 58 # adds an entry >>> dic {"bird": "parrot", "dino": "brontosaur", "parrot age": 58} >>> len(dic) # provides the number of keys 3
Built-In Methods
The following sequence of commands shows the built-in methods that are implemented for
dictionaries.
>>> dic = {"a":1, "b":2, "c":3} >>> dic.keys() # creates a list of keys. Very used in for statements. ["a","b","c"] >>> dic.values() # creates a list of values ["1","2","3"] >>> dic.items() # creates a tuple with the dictionary elements [("a","1"),("b","2"),("c","3")] >>> dic.has_key("a") # returns 1 if key exists. Otherwise it returns 0. 1 # dic.get(value, default) # If key exists, returns its value. Otherwise it returns the second arg. >>> dic.get("b", None) 2 # dic.update(dictionary) # adds the dictionary in the argument to the original dictionary. >>> dic.update({"d":4}) >>> >>> >>> >>> newdic = dic.copy() keys = dic.keys() keys.sort() dic.clear() # creates a copy of the dictionary # sorts the dictionary keys # removes all the items from the dictionary.
Python 2.0 contains a brand-new method for dictionaries, which is called setdefault(). This method returns the value for the given key (exactly as the get() method would do). However, if the given key is not found, it returns the given default value, and at the same time, it initializes the given key with the default value, as demonstrated in the following code.
if dict.has_key( key ): return dict[key] else: dict[key] = ["default value"] return dict[key]
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
converting into lists returning values from functions, tuples setdefault() method stepping backward structures data 2nd 3rd 4th 5th 6th support indexing, tuples syntax tuples tolist() method tuples values returning from functions, tuples xrange() function
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 2. Language Review > Functions and Procedures
CONTINUE >
Python does a search within its namespaces looking for function to identify whether this is a python object. Python creates a tuple of the arguments that were passed. Following our example, we have arguments=(a,b,c). Python invokes the function internally like this: apply( function,arguments ).
As you can see, tuples are an unavoidable concept inside the language. Python, by nature, allows introspection to an unprecedented degree. You can separate a function name from its parameters, store them in some place, play around with them, and later use the apply built-in function to execute the function. Functions Functions always start with the abbreviation def. Their end is defined by the last line of the indented block of code that goes underneath. The general format of a function is as follows:
>>> def addnumbers(x,y): "This function returns arg1 + arg2" return x + y >>> addnumbers(3,4) 9
Remember that to call a function without arguments, it's necessary to use empty parentheses.
x = abs returns the own function, and assigns its value to x. Python uses dynamic namespaces. In order to show that, the next example uses the value of n, available at the time of calling the function, because n isn't defined inside the function nor is it part of its list of arguments. n is part of the global namespace of the function.
Variables that have values assigned to them inside a function always belong to the function namespace. Study the next example to learn how to change a global variable inside a function by using the keyword global.
Python implements procedural abstraction. Although this topic has a scary name, it is something very easy and simple. Python offers this feature by providing anonymous functions implemented with the keyword lambda. This type of abstraction can be used when the function is just an expression. In other words, lambda is just another way of writing def, except that it doesn't have to be named, and you can only put an expression in it. (The return is implicit.) It is intended to be just a shorthand to write small functions easier as shown in the following:
Note that in this last example, it is necessary to pass the default arguments to the lambda function because Python has only local and global namespaces. lambda is very useful for functionssuch as map, filter, and reducethat need a function as an argument.
>>> def listtostring(list): return reduce(lambda string, item: string + chr(item), list, "") >>> listtostring([1,2,3,4,5]) "\001\002\003\004\005"
Parameters
All parameters (arguments) in the Python language are passed by reference. Modules, classes, instances, and other functions can be used as arguments to functions and examined dynamically. Keep in mind that you don't need to specify the object type of an argument. By default, arguments have a positional behavior, and you need to inform them in the same order that they were defined.
Whenever mutable objects (dictionaries and lists)that are transported to a function as argumentschange within the function, their external values also change.
>>> a [1,4]
Python also offers you named arguments. This type is different from positional arguments because it enables you to call a function and pass argument names and values in an arbitrary waythe order isn't important at all. Both function calls
and
are executed perfectly well and in the same way (when the function is implemented, of course). Default arguments are also allowed by the syntax. If the argument isn't provided, the default value takes place. The default value is optional. Even though its absence doesn't break your program, its presence cuts many lines from your code, as shown in the following:
The following example demonstrates namespace handling along with default arguments:
>>> test() 5
This effect is because the value of a was collected when the function was created. In some cases, you cannot pre-identify the number of arguments that you might need. For this kind of situation, you can use the special symbols * and ** next to a generic argument name. *args gets a tuple of values in the received order; **args gets a dictionary mapping argumentname:value.
>>> def showargs(*args): # defines a list of an undefined number of arguments. print args >>> showargs(10,20,30) (10, 20, 30) >>> def add(*args): sum=0 for arg in args: sum=sum+arg return sum >>> add(1,2,3,4) 10 >>> add(1,2,3,4,5,6,7) 28
Returning Values
The return expression halts the execution of a function, but when it's followed by an expression, it returns the expression.
It is also possible for a function to have no return at all. When that happens, the value None is returned.
Built-In Methods
When you have a function f, the following built-in methods can be accessed:
f.__doc__ or f.func_doc # "documentation string" f.__name__ or f.func_name # "function name" f.func_code # byte-compile code f.func_defaults # tuple containing the default arguments f.func_globals # dictionary defining the global namespace
Let's get the documentation string of the join function, which is part of the string module.
>>> import string >>> print string.join.__doc__ join(list [,sep]) -> string joinfields(list [,sep]) -> string Return a string composed of the words in list, with intervening occurences of sep. Sep defaults to a single space. (join and joinfields are synonymous)
Dynamic Namespace
Maybe you haven't noticed yet, but Python uses dynamic namespace concepts. Each function, module, and class defines its own namespace when it is created. When you inform an instruction, command, or statement to Python, it searches first inside the local namespace and afterwards inside the global namespace. Python has the following namespaces: Built-in names int, string, def, print, and so on Global names Declared as global and assigned at the top-level of a module Local names Assigned inside a function When you are writing your code, you have two forms of writing an object name. You can use qualified names and unqualified names. Qualified names use object namespaces as references, for example:
Unqualified names deal with scopes, provided the object is in your namespace. For example
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
modifying global variables inside functions multiple values returning, functions named arguments namespace function 2nd 3rd namespaces dynamic positional arguments procedural abstraction 2nd procedures 2nd 3rd 4th 5th return command returning values tuples returning multiple values, functions user-defined functions values returning variables assigning functions to global changing inside functions
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 2. Language Review > Modules and Packages
CONTINUE >
import <module>
A module filename called yourmodule.py should be mentioned in your import clause as follows:
It is also possible to have multiple modules imported at the same time, using just one import statement as follows:
Tip An interesting fact you should know is that all the code is executed when it is imported for the first time.
Some modules are always available in Python. Others (including yours) are files and need to be imported (in most cases, those files have .py or .pyc suffixes). To be imported, a file must have been saved in one of the directories listed in the sys.path variable. If you need your module to be runnable and importable at the same time, you need to put something like the following line of code at the end of the file:
Tip Remember that in UNIX, you need to change the permission of a file to make it executable.
dir(<module>)
For example,
>>> dir(math)
Now we will talk about packages. A package is a collection of modules in the same directory. Package names must be subdirectories of one of the directories listed in the sys.path variable. A package directory must have, at least, an empty __init__.py file, and it might contain subpackages (subdirectories). Each subdirectory also needs, at least, an empty __init__.py file. In the statement
the module named a.b designates a submodule named b inside a package called a. When you import a package, its subpackages aren't imported all together. You need to explicitly say that in the __init__.py file. It would be similar to saving the following line in the __init__.py file of your package:
Remember that to locate modules and packages, Python uses the paths that are stored at sys.path. This variable is a simple list, like any other, and you can add any directory to this list that you want. Type sys.path at the prompt of your interpreter to know the current contents of this variable. A new feature incorporated to release 2.0 is the possibility to rename modules when importing them. The syntax for that can be either
or
Built-In Methods All these built-in functions are part of the __builtin__ module, and you can use them after you have a module or package named m.
m.__dict__ # lists the module dictionary m.x = m.__dict__["x"] # provides access to a specific attribute m.__doc__ # returns the documentation string m.__name__ # returns the name of the module m.__file__ # returns the file name m.__path__ # returns the fully qualified package name
from in Contrast to import The import and from statements allow one module to refer to objects from another module's namespace. They help eliminate problems with different modules that have some internal names equal. The next examples discuss the possible ways to use these statements.
The previous example imports the string module as a local reference to an external module, allowing fully qualified references to any other objects in the string namespace. The next example adds the join() function to the namespace of the current module. This method allows you to control exactly which names you import into your local namespace from a module.
The problem with this syntax is that if the string module defines its own dosomething() function, you lose the dosomething() that might exist in your current namespace. If you instead do a simple import string, you will keep your current dosomething() function. However, the dosomething() function from the string module will now be accessed by string.dosomething(). Tip The main reason that you don't want to do from <module> import * is to avoid namespace clashing.
Also, let me tell you that identifiers beginning with _ (one underscore), such as _salary, aren't imported by a from <module> import * clause.
The previous example loads the module string from the package package1.
In order to access the string module, you need to reference its objects by typing string.<object>. This is the recommended notation to import a module from a package.
In the syntax form <package.module> import <object>, the <object> can be a subpackage of the package, a function, a class, a variable, and so on.
If you just say from package import *, it isn't guaranteed that all modules will be import unless you insert the following piece of code in the __init__.py file of the package.
__all__ = ["module1","module2","module3"]
This is a list containing the names of the package modules that should be imported:
Whenever you use a structure like package.subpackage.module, Python ensures that the package's __init__.py is loaded first. Afterwards, the subpackage's __init__.py is loaded, and only after they have been imported will the module finally be imported. After a package is loaded, there is no difference between a package and a module. Module objects represent both of them. Releasing and Reloading Modules After you have imported a module, you can release it from the system memory at anytime you want. The following example is to give you an idea of what I am talking about:
import string, sys lst = ["a","b","c","d"] print string.join(lst,"-") del string del sys.modules["string"]
Note that you also need to delete the module's reference, which exists in the sys.module variable.
The command reload <module> reloads and re-executes a module. Note that objects created before the reloading will use the previous version until they are re-created. Try to avoid using this command. You can easily find out what the imported modules are by typing
>>> sys.modules.key() ['os.path', 'operator', 'os', 'exceptions', '__main__', 'ntpath', 'strop', 'nt', 'sys', '__builtin__', 'site', 'signal', UserDict', 'string', 'stat', 'cmath']
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
syntax to rename modules from packages 2nd join() function modules 2nd 3rd 4th renaming syntax string namespaces global importing and creating, modules string packages 2nd 3rd 4th reload module command renaming modules syntax searching contents of modules statements from 2nd 3rd import 2nd 3rd string module string namespace syntax importing and creating global namespaces, modules modulles renaming
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 2. Language Review > Input and Output
CONTINUE >
>>> x = input ("type anything: ") >>> print "You have typed ", x
Note that the input prompt can be anything, even an empty one. If the user types 5, x is properly treated as a number. To make x become a string, the user must explicitly type the quotes. To avoid this problem, you can use the raw_input function:
>>> x = raw_input ("type anything: ") >>> print "You have typed ", x
Now, it doesn't matter whether the user types the quotes. Note that the print command requires objects to be separated by commas:
Displaying Information
Let's delve a little bit deeper into this topic. Python has three standard file objects, which are available from the sys module. The interpreter uses them to provide input and output facilities. (Refer to Chapter 3, "Python Libraries," for details and examplesthe sys module.) They are known as sys.stdin, sys.stdout, sys.stderr print statements are mapped to the sys.stdout. Hence, they send the textual representation of objects to the standard output stream:
Did you know that it is possible to re-map the standard output device? Yes, that is possible. You can run the following code to write to a file:
>>> sys.stdout = open("outputtest.txt", "w") >>> print "hello" >>> sys.stdout.close >>> sys.stdout = sys.__stdout__ >>> sys.exit()
Note that sys.__stdout__ stores the original stdout. The last line restores the sys.__stdout__ original value to such an extent that new print statements will display onscreen, instead of being sent to a file. As additional information, this program uses sys.exit() to quit its execution (refer to Chapter 3 for details).
Starting with release 2.0, the print statement can have its output directed to a file-like object, as it is demonstrated in the following example.
Formatting Operations Python provides formatting operations similar to the printf() function from the C language. Take a look at the following example:
What if you don't want to hard-code the name inside the string? Compare the previous line of code against the following one:
Flexible, don't you think? And by the way, the order of the elements doesn't affect the final result. Therefore, saying
As a matter of fact, the following example shows how Python handles multiple format arguments. Note
that you need to provide a tuple of values to fill the position indicated by the formatting operators (see Table 2.2).
Table 2.2. Formatting Operators Table Formatting Operator %d %i %u %o %x %X %f %e %E %g, %G %s %c %% Description decimal integer decimal integer unsigned integer octal integer hexadecimal integer hexadecimal integer (uppercase letters) floating point as [-]m.dddddd floating point as [-]m.ddddddexx floating point as [-]m.ddddddExx floating point where the exponent is less than -4 or greater than the precision any printable object (such as strings) a single character the literal %
>>> value = 14 >>> print "The value is %d" % value The value is 14
Next, you will see some special ways to format operations by putting special characters between the % literal and the formatting operator. Before going through the examples, we need to initialize some variables.
>>> intg = 42
>>> fltn = 13.142783 >>> strg = "hello" >>> dict = {"xx":13, "yy":1.54321, "zz":"parrot"}
By using the - literal, you can left align the string block.
By using the + literal, you can show positive and negative numerical signs.
Tip A * can be used in the place of any number. It uses the next value that matches that format in a tuple.
Note Python 2.0 contains a new format string called %r, which prints the repr() value of the given argument. You can clearly see the difference between %r and %s by looking at the following example.
'Python'Python
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
modules sys numbers replacing with asterisks (*) operations formatting 2nd output print statements users 2nd 3rd print statement print statements output replacing numbers with asterisks (*) statements print output strings format %r and %s, comparing sys module tuples replacing numbers with asterisks (*) users input and output 2nd 3rd viewing input and output
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 2. Language Review > File Handling
CONTINUE >
File Handling
Python's core language supports all the basic functions that are necessary to manipulate files. It isn't necessary to import any modules to use them. Whenever you use the open function to get access to a file, Python creates a file object that supports all the built-in methods that apply to this new object. Opening a File basic syntax: file = open ( filename[, mode[, buffersize]] ) The mode can be r, w, or a (read, write, and append, respectively). If none of them are mentioned, read mode is assumed. If you are working with a binary file, add the letter b to the mode indicator (for example, rb or wb). The b stands for binary mode ( text translation mode). You can also place a + sign to the mode letter to indicate a read/write open (for example, r+ or w+)it is useful when you need to perform both operations (read and write) in the file. Remember that if you use w+, it will first truncate the file length to zero. The last argument in the open syntax is the buffersize clause, which means
q
0 = unbuffered 1 = line buffered If buffersize is greater than 1, its value is equal to the buffer size, in bytes. If negative, the buffer size is the system default(default behavior).
Here's an example:
line = line[:-1] #chop off the newline character while line: print line line = file.readline() line = line[:-1] file.close()
Supported Methods The following methods are supported by all file objects.
read()
It reads up to n bytes. But, if you don't provide any argument, read() reads all available data from the file. basic syntax: file.read( [nbytes] )
If you say file = open("foo.txt").read(100), Python will read the file up to its first 100 bytes.
readline()
It reads only one line at a time (until, and including, the newline character). basic syntax: file.readline()
Both read() and readline() functions return an empty string for EOF.
readlines()
It reads the entire file into a list of strings. basic syntax: file.readlines()
write()
>>> file.write('Spam')
writelines()
seek()
It goes to a new file position. If how=0, it starts from the beginning of the file; if how=1, the position is relative to the current position; if how=2, the position is relative to the end of the file. The
It truncates the file. basic syntax: file.truncate( [size] ) Now, let's mix two distinct concepts. The next line of code takes the filename and the file extension from two variables, and combines them to create the name of a file that should be opened.
Remember that you need to escape your backslashes to prevent them from being interpreted as beginning a character code. See the next example.
The functions that you saw in this chapter are perfect for handling strings. Chapter 8, "Working with Databases," explains how to use other file handling functions to save entire objects into a file. File Object Attributes Some special attributes for files are as follows:
>>> file.closed # returns 0 if the file is closed; 1 otherwise >>> file.mode # returns the I/O mode for the file >>> file.name # returns the name of the file
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
backslashes (\) file handling 2nd functions handling files 2nd handling files 2nd methods modes append (a) binary (b) read (r) text translation write (w) plus (+) sign r (read) mode read (r) mode statement buffersize syntax close() function Fileno() function flush() function opening files read() function readline() function readlines() function tell() function truncate() function write() function writelines() function text translation mode w (write) mode write (w) mode
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 2. Language Review > Summary
CONTINUE >
Summary
Python is a language that doesn't ask too much from programmers while they are learning it. A programmer can code almost anything using a minimum amount of code. Python provides a commandline interpreter, which is the interface to its shell environment. Python programs can be typed and executed directly in the interpreter or stored and called from files. No matter where the programmer is entering the code, indentation is vital. It is extremely critical that all code blocks follow the indentation rules defined by the language. Python does object reference counting in order to keep you away from the job of deallocating variables by doing its own memory management. The language has two groups of built-in data types that already exist in the interpreter: the immutable data types (for example, strings, numbers, and tuples) and the mutable data types (for example, lists and dictionaries). Python also provides a number of built-in functions that are always available when you load the interpreter. Besides that, it enables you to define and use your own group of functions, which are called user-defined functions. Apart from that, Python also implements procedural abstraction using the function lambda. The basics control statements if, for, and while are provided by Python too. They all have predictable behavior. However, the statements for and while also implement the else structure. Python defines three types of dynamic namespace: built-in names, global names, and local names. This feature allows you to encapsulate your objects within distinct scopes. You can use modules and packages (collections of modules) to store your programs. Both are well supported by Python. All the regular features that provide input and output operations are currently supported by Python. Along with that, Python's core language supports all the basic functions necessary to manipulate files.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing
< BACK
CONTINUE >
Web Development > Python Developer's Handbook > 2. Language Review > Code Example
CONTINUE >
Code Example
This is a very simple benchmark application that offers you a general overview of Python programming. Note that this version doesn't provide any type or error handling and the interface is still very rough. Before going through the code, you must first understand what the program does. Figure 2.4 shows an interaction with the program.
Figure 2.4. This example covers many aspects of basic Python concepts.
The program consists of two questions that should be answered by an n number of companies. These questions cover the number of IT employees and the total IT cost of a company. The benchmark uses the total cost
/ employee value to calculate the statistics. After checking the results, you have the option to save them in a file, and later when opening the application again, you get the option to visualize them again.
Listing 2.1 Benchmark Tool (File benchmark.py)
### # Program: Benchmark tool # Author: Andre S Lessa ### ### import modules import sys import string import operator ### create dictionary of questions
def definequiz(): questions = { } questions["1"] = "What is the number of IT employees of this company?" 17: questions["2"] = "What is the total IT cost of this company?" 18: 19: return questions 20: 21: ### Loop to collect companies data 22: 23: def collectresults(): 24: company = getcompanyname() 25: while company: 26: if company == "": 27: break 28: 29: quizkeys = quiz.keys() 30: quizkeys.sort() 31: for question in quizkeys: 32: showquestion(lo_question=question, lo_company=company) 33: 34: company = getcompanyname() 35: 36: if len(answers) > 0: 37: generateresults() 38: showresults(gl_companies, gl_avg, gl_max, gl_min) 39:
40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86:
userinput = raw_input ("Do you want to save your results ? ") if string.upper(userinput[0]) == "Y": saveresults(gl_companies, gl_avg, gl_max, gl_min) return ### Generate benchmark results def generateresults(): global gl_companies, gl_avg, gl_max, gl_min gl_companies = string.join(answers.keys(), ",") company_count = len(answers.keys()) lo_avg = [] for company in answers.keys(): lo_employees = answers[company][0][1] lo_cost = answers[company][1][1] average = (float(lo_cost) / int(lo_employees)) lo_avg = lo_avg + [average] gl_max = max(lo_avg) gl_min = min(lo_avg) gl_avg = reduce(operator.add, lo_avg) / company_count return ### Interface to enter company name def getcompanyname(): print "Please enter the company name, " } "or press ENTER when you are done." userinput = raw_input() return userinput ### Displays questions and collect results def showquestion(lo_question, lo_company): print quiz[lo_question] if answers.has_key(lo_company): answers[lo_company] = answers[lo_company] + } [coerce(lo_question, raw_input())] else: answers[lo_company] = [coerce(lo_question, raw_input())] return
87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133:
### Save results in a file def saveresults(*arguments): file = open(filename, "w") for value in arguments: file.write(repr(value)+"\ n") file.close showresults(gl_companies, gl_avg, gl_max, gl_min) print "The results were saved." print ### Load results from a file def loadresults(): count = 0 file = open(filename, "r") line = file.readline() line = line[:-1] while line: if count == 0: lo_companies = line if count == 1: lo_avg = float(line) elif count == 2: lo_max = float(line) elif count == 3: lo_min = float(line) line = file.readline() line = line[:-1] count = count + 1 file.close() return(lo_companies, lo_avg, lo_max, lo_min) ### Show results in the screen def showresults(lo_companies, lo_avg, lo_max, lo_min): print "Companies : " print lo_companies print "-------------------------------------" print "%0.2f is the average cost/employees" % lo_avg print "%0.2f is the maximum cost/employees" % lo_max print "%0.2f is the minimum cost/employees" % lo_min print return ### Main action block
134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163:
def main(): print print "Welcome to the benchmark tool!" print userinput = raw_input("Do you want to load the saved results ? ") if userinput == "": collectresults() elif string.upper(userinput[0]) == "Y": gl_companies, gl_avg, gl_max, gl_min = loadresults() showresults(gl_companies, gl_avg, gl_max, gl_min) else: collectresults() print sys.exit() ### Global Variables quiz = definequiz() answers = { } filename = "results.txt" gl_companies = "" gl_avg = 0 gl_max = 0 gl_min = 0 main()
Note that the program effectively starts at line 155, when the global variables are declared, and soon after that, the main() function is executed. The following list shows some of the important concepts that are provided by this simple example. Lines 8-10Loads the required modules. Lines 15-17, 53, 81Dictionary manipulation. The answers dictionary has the following structure: {company1: [(question1,answer1), (question2,answer2), company2: [(question1,answer1), (question2,answer2), }
Note that the dictionary values are lists of tuples. Line 27break statement that exits the while loop. Lines 29,30Sorts dictionary keys. Line 32Named arguments. Line 40User input. Lines 41, 51Uses functions from imported modules. Line 41String manipulation. Lines 53, 63-65Uses built-in functions. Line 90Function with undefined number of arguments. Lines 81-85Creates and inserts a tuple in the dictionary. Line 93Adds a newline character to the value. Line 104Reads a line (delimited by the newline character). Line 105Removes the newline character. Line 127Formats the numbers to display only two decimals. Line 151Exits the application. Line 163Calls to the function that initializes the program.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > Python Libraries
CONTINUE >
Python Libraries
The first chapter has given you a good introduction about the Python core language. Everything you have successfully learned will be applied from now on. All the topics covered in the previous chapters are the building blocks for your Python mastering. Now we will concentrate on this chapter. Python's standard distribution is shipped with a rich set of libraries. These libraries intend to offer flexibility to the programmers. The libraries (also known as modules) cover many topics, such as the following: Python core services A group of modules, such as sys and os, that enable you to interact with what is behind the interpreter. Network and Internet services Python has modules for almost everything that is Internet related. You have many network client protocol implementations that handle the most used Internet services, such as HTTP and FTP. Python also provides support for parsing mark-up languages, like XML and HTML. Regular expressions The re module is a very comprehensive choice for text manipulation because it provides Perl 5 style patterns and matching rules. These are just some of the features implemented by the modules that are reviewed by this chapter. The Library Reference The robustness of Python's library is something amazing. Many users have contributed to the development of these modules during the last few years. Some modules were written in C and are built into the interpreter. Others are written in Python and can be loaded by using the import command. Keep in mind that some of the interfaces may change slightly (for instance, bug fixes) with the next release. Therefore, I suggest that you visit Python's Web site once in a while, and keep yourself up-todate. You can always browse the latest version of the Python Library Reference at
http://www.python.org/doc/lib I encourage you to use this chapter in order to get a quick overview about the existing Python libraries. After you have exhausted all the material provided by this book, check out the online Python Library Reference to see the minor details about each one of these Python module interfaces. This chapter introduces you to the practical side of several modules'utilization. The next pages show what main functions each module exposes, and, whenever possible, some examples are listed. Some of the modulessuch as debugger(pdb), profiler, Tkinter (the standard Python GUI API) and rearen't deeply studied here because they are presented in detail in other chapters of this book. Whenever this happens, the chapter number is mentioned next to the module name. The Standard Library of Modules This book covers the latest version of the Standard Library of Modules that is available at the time of this writing. The modules are presented in the same order as they are shown in Python's official documentation. This was done to make the work of cross-referencing easier for you. The following topics are the group names that organize the modules you will find. Python Services String Miscellaneous Generic Operational System Optional Operational System Debugger Profiler Internet Protocol and Support Internet Data Handling Restricted Execution
Multimedia Cryptographic UNIX Specific SGI IRIX Specific Sun OS Specific MS Windows Specific Macintosh Specific Undocumented Modules
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > Python Services
CONTINUE >
Python Services
This first group of modules is known as Python Services. These modules provide access to services related to the interpreter and to Python's environment. sys The sys module handles system-specific parameters, variables, and functions related to the interpreter. sys.argv This object contains the list of arguments that were passed to a program. If you pass arguments to your program, for example, by saying,
you are able to access those arguments by retrieving the value of sys.argv:
You can use this list to check whether certain parameters are transported to the interpreter.
sys.exit() This is a function used to exit a program. Optionally, it can have a return code. It works by raising the SystemExit exception. If the exception remains uncaught while going up the call stack, the interpreter shuts
The return_code argument indicates the return code that should be passed back to the caller application. The sys module also contains three file objects that take care of the standard input and output devices (see Chapter 1, "Introduction," for more details about these objects). sys.stdin File object that is used to read data from the standard input device. Usually it is mapped to the user keyboard. sys.stdout File object that is used by every print statement. The default behavior is to output to the screen. sys.stderr It stands for standard error output. Usually, it is also mapped to the same object of sys.stdout. Example:
import sys data = sys.stdin.readlines() str = "Counted %d lines." % len(data) sys.stdout.write (str)
Now, save the previous example in a file named countlines.py, and test it by typing the following instructions on your prompt:
On Unix: cat coutlines.py | python countlines.py On DOS and Windows: type countlines.py | python countlines.py
sys.modules It is a dictionary that contains the modules that were loaded by the current session.
sys.platforms This is a string that shows the current platform (for example, "win32", "mac", "linux-i386"). You can test which platform is running a program by doing something like this:
if sys.platforms == "win32" <do something> elif sys.platform == "mac" <do something else>
sys.path This is the list of directories that are searched to find the location of a module at the time of importing it.
>>> import.sys >>> sys.path ['', 'C:\\Program Files\\Python\\Lib\\plat-win', 'C:\\Program Files\\Python\\Lib', 'C:\\Program Files\\Python\\DLLs', 'C:\\Program Files\\Python\\Lib\\lib-tk','C:\\PROGRAM FILES\\PYTHON\\DLLs', 'C:\\PROGRAM FILES\\PYTHON\\lib', 'C:\\PROGRAM FILES\\PYTHON\\lib\\plat-win', 'C:\\PROGRAM FILES\\PYTHON\\lib\\lib-tk', 'C:\\PROGRAM FILES\\PYTHON']
You can easily update this list to include your own directories. sys.builtin_module_names This is the list of modules that are not imported as files.
>>> import sys >>> sys.builtin_module_names ('__builtin__', '__main__', '_locale', '_socket', 'array', 'audioop', 'binascii', 'cPickle', 'cStringIO', 'cmath', 'errno', 'imageop', 'imp', 'marshal', 'math', 'md5', 'msvcrt', 'new', 'nt', 'operator', 'pcre', 'regex', 'rgbimg', 'rotor', 'select', 'sha', 'signal', 'soundex', 'strop', 'struct', 'sys', 'thread', 'time', 'winsound')
For all the next sys objects, see Chapter 4, "Exception Handling," for details. sys.exc_info() Provides information about the current exception being handled. sys.exc_type, sys.exc_value, sys.exc_traceback It is another way to get the information about the current exception being handled. sys.last_type, sys.last_value and sys.last_traceback Provides information about the last uncaught exception. Python 2.0 contains a mode detailed version information function called sys.version_info. This function returns a tuple in the format (major, minor, micro, level, serial). For example, suppose the version number of your Python system is 3.0.4alpha1, the function sys.version_info() returns (3, 0, 4, 'alpha', 1). Note that the level can be one of the following values: alpha, beta, or final. Another set of functions added to Python 2.0 are: sys.getrecursionlimit() and sys.setrecursionlimit(). These functions are responsible for reading and modifing the maximum recursion depth for the routines in the system. The default value is 1000, and you can run the new script Misc/find_recursionlimit.py in order to know the maximum value suggested for your platform.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
sys 2nd 3rd objects file sys module Python Services 2nd return code argument syntax sys.exit() function sys module 2nd 3rd sys.exec.traceback() function sys.exec.value() function sys.getrecursionlimit() function sys.last.value() function sys.recursionlimit() function sys.version_info() function
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 3. Python Libraries > types
CONTINUE >
types
The types module stores the constant names of the built-in object types. FunctionType, DictType, ListType, and StringType are examples of the built-in type names. You can use these constants to find out the type of an object.
>>> import types >>> if type("Parrot") == types.StringType: Print "This is a string!" This is a string
The complete list of built-in object types, that are stored at the types module, can be found in Chapter 5, "Object-Oriented Programming."
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > UserDict
CONTINUE >
UserDict
The UserDict module is a class wrapper that allows you to overwrite or add new methods to dictionary objects.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > UserList
CONTINUE >
UserList
The UserList module is a class wrapper that allows you to overwrite or add new methods to list objects.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark 2002, O'Reilly & Associates, Inc. CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > operator
CONTINUE >
operator
The operator module stores functions that access the built-in standard operators. The main reason for the operator module is that operator.add, for instance, is much faster than lambda a,b: a+b. For example, the line
>>> 6 / 2 3
This module is mostly used when it becomes necessary to pass an operator as the argument of a function. For example
1: import sys, glob, operator 2: sys.argv = reduce(operator.add, map(glob.glob, sys.argv)) 3: print sys.argv
To run the previous example, save the code in a file and execute it by switching to your OS prompt and typing:
The heart of this example is Line 2. Let's interpret it: The glob.glob() function is applied for each element of the original sys.argv list object (by using the map() function). The result is concatenated and reduced into a single variable sys.argv. The concatenation operation is performed by the operator.add() function.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > traceback
CONTINUE >
traceback
The traceback module supports print and retrieve operations of the traceback stack. This module is mostly used for debugging and error handling because it enables you to examine the call stack after exceptions have been raised. See Chapter 4 for more details about this module.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > linecache
CONTINUE >
linecache
The linecache module allows you to randomly access any line of a text file. For example, the next lines of code belong to the file c:\ temp\ interface.py.
import time, sys name = raw_input("Enter your name: ") print "Hi %s, how are you?" % name feedback = raw_input("What do you want to do now? ") print "I do not want to do that. Good bye!" time.sleep(3) sys.exit()
Check the result that is retrieved when the function linecache.getline(file,linenumber) is called.
>>> import linecache >>> print linecache.getline("c:\ \ temp\ interface.py",4) feedback = raw_input("What do you want to do now? ")
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark 2002, O'Reilly & Associates, Inc. CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > pickle
CONTINUE >
pickle
The pickle module handles object serialization by converting Python objects to/from portable strings (byte-streams). See Chapter 8, "Working with Databases," for details.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > cPickle
CONTINUE >
cPickle
The cPickle module is a faster implementation of the pickle module. See Chapter 8 for details.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > copy_reg
CONTINUE >
copy_reg
The copy_reg module extends the capabilities of the pickle and cpickle modules by registering support functions. See Chapter 8 for details.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark 2002, O'Reilly & Associates, Inc. CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > shelve
CONTINUE >
shelve
The shelve module offers persistent object storage capability to Python by using dictionary objects. The keys of these dictionaries must be strings and the values can be any object that the pickle module can handle. See Chapter 8 for more details.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark 2002, O'Reilly & Associates, Inc. CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > copy
CONTINUE >
copy
The copy module provides shallow and deep object copying operations for lists, tuples, dictionaries, and class instances. copy.copy() This function creates a shallow copy of the x object.
import copy x = [1, 2, 3, [4, 5, 6]] y = copy.copy(x) print y 2, 3, [4, 5, 6]] id(y) == id(x)
As you can see at the end of the previous example, the new list is not the old one. As you can see, this function provides the same result that y=x[:] does. It creates a new object that references the old one. If the original object is a mutable object and has its value changed, the new object will change too. copy.deepcopy() It recursively copies the entire object. It really creates a new object without any link to the original structure. basic syntax: variable = copy.deepcopy(object)
>>> listthree = copy.deepcopy(listone) >>> listone[0]["name"] = "Renata" >>> listone.append("Python") >>> print listone, listtwo, listthree [{ "name":"Renata"} , 3, 2, "Python"] [{ "name":"Renata"} , 3, 2] [{ "name":"Andre} , 3, 2]
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > marshal
CONTINUE >
marshal
The marshal module is an alternate method to implement Python object serialization. It allows you to read/write information in a binary format, and convert data to/from character strings. Basically, it is just another way to do byte stream conversions by using serialized Python objects. It is also worth mentioning that marshal is used to serialize code objects for the .pyc files. This module should be used for simple objects only. Use the pickle module to implement persistent objects in general. See Chapter 8 for details.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > imp
CONTINUE >
imp
The imp module provides mechanisms to access the internal import statement implementation. You might want to use this module to overload the Python import semantics. Note that the ihooks module provides an easy-to-use interface for this task. imp.find_module() This function identifies the physical location of a given module name. basic syntax: file, path, desc = imp.find_module(modulename) imp.load_module() This one loads and returns a module object based on the information provided. basic syntax: obj = imp.load_module(modulename,file,path,desc)
>>> import imp >>> def newimport(modulename): file, path, desc = imp.find_module(modulename) moduleobj = imp.load_module(modulename,file,path,desc) return moduleobj math = newimport(math) math.e 2.71828182846
imp.getsuffixes() It lists the precedence order in which files are imported when using the import statement. Typing the following commands in my environment accomplishes this:
>>> imp.get_suffixes() [('.pyd', 'rb', 3), ('.dll', 'rb', 3), ('.py', 'r', 1), ('.pyc', 'rb', 2)]
Note that if I have a module stored in a file called mymodule.pyc, and I enter the command import mymodule at the interpreter, the system initially searches for a file called mymodule.pyd, and then for one called mymodule.dll, one called mymodule.py, and finally it searches for a file called mymodule.pyc. Tip When importing packages, this concept is ignored because directories precede all entries in this list.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > parser
CONTINUE >
parser
The parser module offers you an interface to access Python's internal parser trees and code compiler.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark 2002, O'Reilly & Associates, Inc. CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > symbol
CONTINUE >
symbol
The symbol module includes constants that represent the numeric values of internal nodes of Python's parse trees. This module is mostly used along with the parser module.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > token
CONTINUE >
token
The token module is another module that is used along with the parser module. It stores a list of all constants (tokens) that are used by the standard Python tokenizer. These constants represent the numeric values of leaf nodes of the parse trees.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark 2002, O'Reilly & Associates, Inc. CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > keyword
CONTINUE >
keyword
The keyword module tests whether a string is a Python keyword. Note that the keyword-checking mechanism is not tied to the specific version of Python being used. keyword.kwlist This is a list of all Python keywords.
>>> import keyword >>> keyword.kwlist ['and', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'exec', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'not', 'or', 'pass', 'print', 'raise', 'return', 'try', 'while']
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark 2002, O'Reilly & Associates, Inc. CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > tokenize
CONTINUE >
tokenize
The tokenize module is an analysis tool that provides a lexical scanner for Python source code.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > pyclbr
CONTINUE >
pyclbr
The pyclbr module offers class browser support in order to provide information about classes and methods of a module. See Chapter 5 for details.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark 2002, O'Reilly & Associates, Inc. CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > code
CONTINUE >
code
The code module interprets base classes, supporting operations that pertain to Python code objects. In other words, it can simulate the standard interpreter's interactive mode. The next code opens a new interpreter within your interpreter:
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > codeop
CONTINUE >
codeop
The codeop module offers a function to compile Python code. This module is accessed by the code module and shouldn't be used directly.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > pprint
CONTINUE >
pprint
The pprint (pretty printer) module prints Python objects so that the interpreter can use them as input for other operations.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark 2002, O'Reilly & Associates, Inc. CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > repr
CONTINUE >
repr
The repr module is an alternate repr() function implementation that produces object representations that limit the size of resulting strings.
>>> import repr >>> var = ["Spam" * 10] >>> print var ['SpamSpamSpamSpamSpamSpamSpamSpamSpamSpam'] >>> print repr.repr(var) ['SpamSpamSpammSpamSpamSpam']
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > py_compile
CONTINUE >
py_compile
The py_compile module is a single function that compiles Python source files, generating a bytecode file.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > compileall
CONTINUE >
compileall
The compileall module compiles all Python source files that are stored in a specific directory tree. Note that compileall uses py_compile. compileall.compile_dir() This function byte-compiles all source files stored in the provided directory tree. basic syntax: compile.compile_dir(directory)
>>> import compileall >>> compileall.compile_dir("c:\\temp") Listing c:\temp Compiling c:\temp\program3.py Compiling c:\temp\program4.py Compiling c:\temp\program5.py 1
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > dis
CONTINUE >
dis
The dis module is a Python byte-code dissassembler. This module enables you to analyze Python byte-code.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > new
CONTINUE >
new
The new module implements a runtime interface that allows you to create various types of objects such as class objects, function objects, instance objects, and so on.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark 2002, O'Reilly & Associates, Inc. CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > site
CONTINUE >
site
The site module performs site-specific packages'initialization. This module is automatically imported during initialization.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark 2002, O'Reilly & Associates, Inc. CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > user
CONTINUE >
user
The user module is a user-specific mechanism that allows one user to have a standard and customized configuration file.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark 2002, O'Reilly & Associates, Inc. CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > __builtin__
CONTINUE >
__builtin__
The __builtin__ module is a set of built-in functions that gives access to all built-in Python identifiers. You don't have to import this module because Python automatically imports it. Most of the content of this module is listed and explained in the section "Built-In Functions" of Chapter 2, "Language Review."
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark 2002, O'Reilly & Associates, Inc. CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > __main__
CONTINUE >
__main__
The __main__ module is the top-level script environment object in which the interpreter's main program executes. This is how the if __name__ == '__main__' code fragment works.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > The String Group
CONTINUE >
This function splits a string into a list. If the delimiter is omitted, white-spaces are used. basic syntax: string.split(string [,delimiter])
string.atof()
It converts a string to an integer. atoi takes an optional second argument: base. If omitted, the start of the string (for instance, 0x for hexadecimal) is used to determine the base.
It converts a string to a long integer. atol takes an optional second argument: base. If omitted, the start of the string (for instance, 0x for hexadecimal) is used to determine the basic syntax: string.atol(string[, base])
string.upper()
It returns the index position of the substring within string. Optionally, you can specify the string's range that should be used in the search. basic syntax: string.find(string, substring[, start [,end]])
string.join()
This function joins the string elements of a list using separator to separate them. basic syntax: string.join(list, separator)
string.capitalize()
This function capitalizes the first letter of each word in string and removes repeated, leading, and trailing whitespace. basic syntax: string.capwords(string)
string.lower()
These functions remove leading and/or trailing whitespace from string. basic syntaxes:
These functions define the alignment of string within a variable of width characters. basic syntaxes:
string.replace()
It replaces a maximum number of occurrences of oldtext with newtext in string. If maximum is omitted, all occurrences are replaced. basic syntax: string.replace(string, oldtext, newtext [,maximum])
string.zfill()
It inserts zeros on the left side of a string that has width characters.
basic syntax: string.zfill(string, width) Next, I list a few constants that can be used to test whether a certain variable is part of a specific domain:
>>> import string >>> string.digits "0123456789" >>> string.octdigits "01234567" >>> string.uppercase "ABCDEFGHIJKLMNOPQRSTUVWXY" >>> string.hexdigits "0123456789abcdefABCDEF" >>> string.lowercase "abcdefghijklmnopqrstuvwxy"
>>> text = "F" >>> if text in string.uppercase: print "%s is in uppercase format" % text "F is in uppercase format"
string.maketrans()
Returns a translation table that maps each character in the from string into the character at the same position in the to string. Then this table is passed to the translate function. Note that both from and to must have the same length. basic syntax: string.maketrans(from, to)
string.translate()
Based on the given table, it replaces all the informed characters, according to the table created by the string.maketrans function. Optionally, it deletes from the given string all characters that are
presented in charstodelete. basic syntax: string.translate(string, table[, charstodelete]) re The re module performs Perl-style regular expression operations in strings, such as matching and replacement. Tip As a suggestion, always use raw string syntax when working with regular expression because it makes the work of handling special characters simpler.
>>> import re >>> data = r"Andre Lessa" >>> data = re.sub("Lessa", "L.", data) >>> print data Andre L.
See Chapter 9, "Other Advanced Topics," for more details about creating regular expression patterns. Note It is expected that in version 1.6, the re module will be changed to a front end to the new sre module.
regex The regex module is an obsolete module since Python version 1.5. This module used to support regular expression search and match operations. If necessary, you can use the regex-to-re HOWTO to learn how to migrate from the regex
module to the re module. Check out the address http://www.python.org/doc/howto/regex-to-re/. regsub The regsub module is another obsolete module. It also handles string operations (such as substitution and splitting) by using regular expressions. The functions in this module are not thread-safe, so be careful. struct The struct module interprets strings as packed binary data. It processes binary files using the functions pack(),unpack(), and calcsize(). This module allows users to write platformindependent, binary-file manipulation code when using the big-endian or little-endian format characters. Using the native formats does not guarantee platform independence. fpformat The fpformat module provides functions that deal with floating point numbers and conversions. StringIO The StringIO module creates a string object that behaves like a file, but actually, it reads and writes data from string buffers. The StringIO class, which is exposed by the StringIO module supports all the standard file methods.
>>> import StringIO >>> str = StringIO.StringIO("Line 1\ nLine 2\ nLine 3") >>> str.readlines() ['Line1\ 012', 'Line2\ 012', 'Line3']
An additional method provided by this class is StringIO.getvalue() It returns and closes the string object. basic syntax: variable = stringobject.getvalue()
>>> str = StringIO.StringIO() >>> str.write(text) >>> result = str.getvalue() "Line 1\ 012Line 2\ 012Line 3"
cStringIO The cStringIO is a faster version of the StringIO module. The difference is that you cannot subclass this module. It is necessary to use StringIO instead.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
regex module String Group library 2nd 3rd 4th 5th 6th string module 2nd 3rd 4th string.rjust() function string.rstrip() function string.uppercase() function StringIO.getvalue() method syntax functions string.atof() string.atoi() string.capitalize() string.capwords() string.center() 2nd string.find() string.join() string.ljust() string.lower() string.lstrip() string.maketrans() string.replace() string.rjust() string.rstrip() string.split() string.translate() string.upper() string.zfill() raw string StringIO.getvalue() method unpack() function
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 3. Python Libraries > Miscellaneous
CONTINUE >
Miscellaneous
This group handles many functions that are available for all Python versions. math The math module provides standard mathematical functions and constants. It doesn't accept complex numbers, only integers and floats. Check out the following example:
import math >>> math.cos(180) -0.598460069058 >>> math.sin(90) 0.893996663601 >>> math.sqrt(64) 8.0 >>> math.log(10) 2.30258509299 >>> math.pi # The mathematical constant pi 3.14159265359 >>> math.e # The mathematical constant e 2.71828182846
cmath The cmath module also provides standard mathematical functions and constants. However, its implementation enables it to accept complex numbers as arguments. All the returned values are expressed as complex numbers. random The random module generates pseudo-random numbers. This module implements all the randomizing functions provided by the whrandom module plus several pseudo-random real number generators. These random modules aren't very secure for encryption purposes.
random.choice()
>>> lst = ["A","l","b","a","t","r","o","s","s","!","!"] >>> while lst: element = random.choice(lst) lst.remove(element) print element, # inserts a linefeed b l o A s r ! ! t s a
random.random()
It returns a random floating-point number between 0.0 and 1.0. basic syntax: random.random()
random.randint()
It returns a random integer n, where x <= N <= y. basic syntax: random.randint(x,y) whrandom The whrandom module provides a Wichmann-Hill floating-point pseudo-random number generator. This module is mostly useful when you need to use multiple independent number generators.
whrandom.whrandom()
This function initializes multiple random generators using the same seed.
bisect The bisect module has an array bisection algorithm that provides support for keeping lists in sorted order without the need for sorting them out all the time. array The array module is a high efficiency array implementation that handles large lists of objects. The array type is defined at the time of creation. By using this module, you can create an ArrayType object that behaves exactly like any other list, except that it isn't recommended for storing elements of different types.
>>> import array >>> s = "This is a string" >>> a = array.array("c", s) >>> a[5:7] = array.array("c", "was") >>> print a.tostring() This was a string
Note that NumPy provides a superior array implementation, which can be used for more than just numeric algorithms. Note that Python 2.0 has improved the array module, and new methods were added to its array objects, including: count(), extend(), index(), pop(), and remove(). ConfigParser The ConfigParser module is a basic configuration file parser that handles structures similar to those found in the Microsoft Windows INI file.
Note Note that as of Release 2.0, the ConfigParser module is also able to write config files as well as read them.
fileinput The fileinput module helps you by writing a loop that reads the contents of a file, line by line.
>>> import fileinput >>> for line in fileinput.input("readme.txt"): if line.isfirstline: print "<< This is the first line >>" print "filename = %s" % line.filename print " ---------------------------" else: print "<< This is the line number %d>>" % line.lineno print line
calendar The calendar module provides general calendar-related functions that emulate the UNIX cal program, allowing you to output calendars, among other things. cmd The cmd module is a simple interface used as a framework for building command line interpreters and shells. You just need to subclass its cmd.Cmd class in order to create your own customized environment. shlex The shlex module helps you write simple lexical analyzers (tokenizers) for syntaxes that are similar to the UNIX shell.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > Generic Operational System
CONTINUE >
This is a dictionary that contains all the environment variables. You can search for a specific variable:
os.name
# "posix","dos","mac","nt"
os.getcwd()
os.curdir
This is a simple constant that returns the OS-specific string used to identify the current directory.
os.listdir()
If directory is omitted, it lists the filenames of the current directory. Otherwise, it lists the filenames of directory. basic syntax: os.listdir([directory])
os.rename()
It changes the file mode. This is a UNIX command. basic syntax: os.chmod(file, mode)
os.system()
It opens an Operating System subshell and executes the command. basic syntax: os.system(command)
os.popen()
This is a UNIX function that returns a file-like object. It allows you to execute a shell command and read the standard
output of external pipes (by setting mode to r) or write to their standard input (by setting mode to w). The default mode is r. Note that even though popen is a UNIX function, it is also implemented on the other Python ports. basic syntax: os.popen(shell command, mode)
file = os.popen('sed \ 's/yes/no/g'> output','w') file.write("yes\ n") file = os.popen('cat manual.txt', 'r') f = file.read()
os.remove()
It is a wrapper for rmdir that deletes everything under the directory. basic syntax: os.removedirs(directory) os.path The os.path is a module imported by the os module that exposes useful common functions to manipulate pathnames. Remember that you don't have to explicitly import os.path. You get it for free when you import os.
os.path.exists()
It splits filename, returning a tuple that contains the directory structure and filename, which together combine the original filename argument. basic syntax: os.path.split(filename) dircache The dircache module reads directory listings using a cache. Note that this module will be replaced by the new module filecmp in Python 1.6. stat The stat module works along with the os module by interpreting information about existing files that is extracted by the os.stat() function and stored on a tuple structure. This tuple contains the file size, the file owner group, the file owner name, the last accessed and last modified dates, and its mode. statcache The statcache module is a simple optimization of the os.stat() function. statvfs The statvfs module stores constants that are used to interpret the results of a call to the os.statvfs() function. By the way, the os.statvfs provides information about your file system.
import statvfs, os stat = os.statvfs(".") maxfnl = stat[statvfs.F_NAMEMAX] print "%d is the maximum file name length" % maxfnl print "that is allowed on your file system."
cmp
The cmp module is used to compare files. Note that this module will be replaced by the new module filecmp in Python 1.6. cmpcache The cmpcache module is a more efficient version of the cmp module for file comparisons. Note that this module will be replaced by the new module filecmp in Python 1.6. time The time module exposes functions for time access and conversion. It is important to remember that there are no Year 2000 issues in the Python language.
time.time()
It returns the current timestamp in seconds since the UNIX epoch began (start of 1970, UTC - Universal Time Coordinated). basic syntax: time.time()
time.localtime()
It converts a time expressed in seconds into a time tuple. This tuple has the following format: (4digitsyear, month, day, hour, minute, second, day of week, day of year, daylight savings flag). basic syntax: time.locatime(seconds)
time.asctime()
>>> import time >>> time.time() 957044415.14 >>> time.localtime(time.time()) (2000, 4, 29, 17, 42, 14, 5, 120, 1) >>> time.asctime(time.localtime(time.time())) 'Sat Apr 29 17:42:59 2000'
time.sleep()
It suspends the execution of a program for a specific number of seconds. basic syntax: time.sleep(seconds)
>>> time.sleep(10)
sched The sched module implements a general-purpose event scheduler. getpass The getpass module implements a portable function that enables the user to type a password without echoing the entry in the screen. basic syntax: getpass.getpass([prompt]) This module also provides a function to collect information about the user's login. basic syntax: getpass.getuser()
import getpass defaultpwd = "Ahhhhh" user = getpass.getuser() print "Hello %s," % user pass = getpass.getpass("Please, type the password. ") if pass == defaultpwd: print "Welcome back to the system!! else: print r"You've just activated the detonation process.Sorry"
curses The curses module is a terminal independent I/O interface to the curses UNIX library. For more details, check out the curses HOWTO at http://www.python.org/doc/howto/curses/curses.html. getopt The getopt module is a parser for command-line options and arguments (sys.argv). This module provides the standard C getopt functionality.
1: 2: 3: 4: 5: 6: 7:
>>> import getopt >>> args = ['-h','-r','origin.txt','file','work.txt','755','777'] >>> opts, pargs = getopt.getopt(args, 'hr:', ['file=']) >>> opts [('-h', ''), ('-r','origin.txt') , ('file','work.txt')] >>> pargs ['755','777']
Before transporting arguments to this function, line 2 shows you that single options must be preceded by a single hyphen and long options must be preceded by double hyphens. In line 3, note that single options that require an argument must end with a colon. On the other hand, long options that require an argument must end with an equal sign. The getopt.getopt() returns two values: A tuple that contains pairs of (option, argument) values (line 5), and a list of standalone arguments that aren't associated with any options (line 7). tempfile The tempfile module generates unique temporary filenames based on templates defined by the variables tempfile.tempdir and tempfile.template.
tempfile.mktemp()
This function returns a temporary filename. It doesn't physically create or remove files. basic syntax: filename = tempfile.mktemp()
tempfile.TemporaryFile()
This function returns a file object that is saved in your temporary local folder (/tmp or c:/temp, for example). The system removes this file after it gets closed. basic syntax: fileobject = tempfile.TemporaryFile() errno The errno module makes available the standard errno system symbols, such as EACCES, EADDRINUSE, and EDEADLOCK. Each symbol is associated to a constant error code value.
More information about this module and its symbols is provided in Chapter 4. glob The glob module finds and returns pathnames matching a specific pattern, just like the UNIX shell does. basic syntax: glob.glob(pattern)
>>> import glob >>> lst = glob.glob("c:\ \ *.txt") >>> print lst ['c:\ \ FRUNLOG.TXT', 'c:\ \ DETLOG.TXT', 'c:\ \ BOOTLOG.TXT', 'c:\ \ SETUPLOG.TXT', 'c:\ \ NETLOG.TXT', 'c:\ \ RESETLOG.TXT']
fnmatch The fnmatch module uses wildcards to provide support for UNIX shell-style filename pattern matching. These wildcards are different from those normally used by the re module.
fnmatch.fnmatch()
This function returns 1 (true) if the provided filename matches the pattern defined. basic syntax: fnmatch.fnmatch()filename, pattern)
fnmatch.translate()
This function converts a fnmatch-style pattern into a regular expression. basic syntax: variable == fnmatch.translate(pattern)
shutil The shutil module provides high-level file operations. Essentially, it offers many file-copying functions and one directory
removal function.
shutil.copyfile()
It makes a straight binary copy of the source file, calling it newcopy. basic syntax: shutil.copyfile(source, newcopy)
shutil.rmtree()
It deletes the path directory, including all of its subdirectories, recursively. If ignore_errors is set to 0, errors are ignored. Otherwise, the onerror function argument is called to handle the error. If the clause onerror is set to None, an exception is raised when an error occurs. basic syntax: shutil.rmtree(path, ignore_errors=0, onerror=None) locale The locale module provides access to the POSIX locale mechanism, enabling internationalization services. This module defines a set of parameters that describe the representation of strings, time, numbers, and currency. The good thing about using this module is that programmers don't have to worry about the specifics of each country where their applications are executed. mutex The mutex module defines a mutex class that allows mutual-exclusion support via acquiring and releasing locks.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
libraries Generic Operational System 2nd 3rd 4th 5th 6th 7th 8th 9th listing variables modules cmp curses fnmatch mutex os 2nd 3rd os.path 2nd sched shutil 2nd stat tempfile mutex module os module 2nd 3rd os.path module 2nd os.statvfs() function sched module searching variables shutil module 2nd stat module syntax functions fnmatch.fnmatch() fnmatch.translate() getpass.getpass() getpass.getuser() glob.glob() os.chmod() os.listdir() os.mkdir() os.path.exists() os.path.isdir() os.path.isfile() os.path.split() os.popen() os.remove() os.removedirs() os.rename() os.rmdir() os.system() shutil.copyfile() shutil.rmtree() tempfile.mktemp() tempfile.Temporary File() time.asctime() time.sleep() time.time() tempfile module variables finding listing
Web Development > Python Developer's Handbook > 3. Python Libraries > Optional Operational System
CONTINUE >
import signal, sys def signal_handler(signal, frame): print "You have pressed CTRL+C" signal.signal(signal.SIGINT, signal.SIG_IGN) print "Now, you can\ 't stop the script with CTRL+C " } "for the next 10 seconds!" signal.signal(signal.SIGALRM, alarm_handler) signal.alarm(10) while 1: print "I am looping" def alarm_handler(signal, frame): print "Now you can leave the program" sys.exit(0) signal.signal(signal.SIGINT, signal_handler) print "Press CTRL+C" while 1: continue
socket The socket module provides access to a low-level BSD socket-style network interface. See Chapter 10, "Basic Network Background," for details. select The select module is used to implement polling and to multiplex processing across multiple I/O streams without using threads or subprocesses. It provides access to the BSD select() function interface, available in most operating systems. On windows it only works for sockets. On UNIX, it is used for pipes, sockets, files, and so on. See Chapter 10 for details. thread The thread module supports lightweight process threads. It offers a low-level interface for working with multiple threads. See Chapter 9 for details. threading The threading module provides high-level threading interfaces on top of the thread module. See Chapter 9 for details. Queue
The Queue module is a synchronized queue class that is used in thread programming to move Python objects between multiple threads. See Chapter 9 for details. anydbm The anydbm module is a generic dbm-style interface to access variants of the dbm database. See Chapter 8 for details. dumbdbm The dumbdbm module is a simple, portable, and slow database implemented entirely in Python. See Chapter 8 for details. dbhash The dbhash module provides a function that offers a dbm-style interface to access the BSD database library. See Chapter 8 for details. whichdb The whichdb module provides a function that guesses which dbm module (dbm, gdbm, or dbhash) should be used to open a specific database. See Chapter 8 for details. bsddb The bsddb module provides an interface to access routines from the Berkeley db library. See Chapter 8 for details. zlib
The zlib module provides functions that allow compression and decompression using the zlib library. The compression that is provided by this module is compatible with gzip. For more details check out the zlib library home page at http://www.cdrom.com/pub/infozip/lib. gzip The gzip module offers support for gzip files. This module provides functions that allow compression and decompression using the GNU compression program gzip. This module has a class named GzipFile that can be used to read and write files compatible with the GNU gzip program. The objects that are generated by this class behave just like file objects. The only exception is that the seek and tell methods aren't part of the standard implementation.
rlcompleter The rlcompleter module provides a completion function for the readline module. The readline module is a UNIX module that is automatically imported by rlcompleter. It uses a compatible GNU readline library to activate input editing on UNIX.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > Debugger
CONTINUE >
Debugger
The pdb module defines an interactive source code debugger for Python programs. You can use this tool to verify and modify variables and to set and examine breakpoints. It allows inspection of stack frames, single stepping of source lines, and code evaluation. This module is based on the module bdb, which implements a generic Python debugger base class. See Chapter 17,"Development Tools," for details.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > Profiler
CONTINUE >
Profiler
The profiler module is a code execution profiler. This tool can be used to analyze statistics about the runtime performance of a program. It helps you to identify what parts of your program are running slower than the expected and what can be done to optimize it. The pstats module works along with the profiler module in order to analyze the collected data. See Chapter 17 for details.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > Internet Protocol and Support
CONTINUE >
The ftplib module implements the client side of the FTP protocol. You can use it for mirroring FTP sites. Usually the urllib module is used as an outer interface to ftplib. See Chapters 10 and 12 for details. gopherlib The gopherlib module is a minimal client-side implementation of the Gopher protocol. poplib The poplib module provides a low-level, client-side interface for connecting to a POP3 server using a client protocol, as defined in the Internet standard RFC 1725. See Chapter 10 for details. imaplib The impalib module provides a low-level, client-side interface for connecting to an IMAP4 mail server using the IMAP4rev1 client protocol, as defined in the Internet standard RFC 2060. See Chapter 10 for details. nntplib The nntplib module implements a low-level interface to the client side of the NNTP (Network News Transfer Protocol) protocola service mostly known for implementing newsgroups. See Chapter 10 for details. smtplib The smtplib module provides a low-level client interface to the SMTP protocol that can be used to send email to any machine in the Internet that has an SMTP or ESMTP listener daemon. See Chapter 10 for details. telnetlib The telnetlib module implements a client for the telnet protocol.
urlparse The urlparse module manipulates a URL string, parsing it into tuples. It breaks a URL up into components, combines them back, and converts relative addresses to absolute addresses. See Chapters 10 and 12 for details. SocketServer The SocketServer module exposes a framework that simplifies the task of writing network servers. Rather than having to implement servers using the low-level socket module, this module provides four classes that implement interfaces to the mostly used protocols: TCPServer, UDPServer, UnixStreamServer, and UnixDatagramServer. All these classes process requests synchronously. See Chapter 10 for details. BaseHTTPServer The BaseHTTPServer module defines two base classes for implementing basic HTTP servers (also known as Web servers). See Chapter 10 for details. SimpleHTTPServer The SimpleHTTPServer module provides a simple HTTP server request-handler class. It has an interface compatible with the BaseHTTPServer module that enables it to serve files from a base directory. See Chapter 10 for details. CGIHTTPServer The CGIHTTPServer module defines a simple HTTP server request-handler class. It has an interface compatible with BaseHTTPServer that enables it to serve files from a base directory, but it can also run CGI scripts. See Chapters 10 and 12 for details.
asyncore The asyncore module provides the basic infrastructure for writing and handling asyncronous socket service clients and servers that are the result of a series of events dispatched by an event loop. See Chapter 10 for details.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > Internet Data Handling
CONTINUE >
headers of this form are used in a number of contexts including mail handling and in the HTTP protocol. mimetools The mimetools module provides utility tools for parsing and manipulation of MIME multipart and encoded messages. Tip MIME (multipurpose Internet mail extensions) is a standard for sending multipart multimedia data through Internet mail.
MimeWrite The MimeWrite module implements a generic file-writing class that is used to create MIME-encoded multipart files. multifile The multifile module enables you to treat distinct parts of a text file as file-like input objects. Usually, this module uses text files that are found in MIME encoded messages. binhex The binhex module encodes and decodes files in binhex4 format. This format is commonly used to represent files on Macintosh systems. uu The uu module encodes and decodes files in uuencode format. This module does its job by transferring binary data over an ASCII-only connection. binascii The binascii module implements methods to convert data between binary and various ASCIIencoded binary representations.
base64 The base64 module performs base64 encoding and decoding of arbitrary binary strings into text strings that can be safely emailed or posted. This module is commonly used to encode binary data in mail attachments. xdrlib The xdrlib module is used extensively in applications involving Remote Procedure Calls (RPC). Similarly, it is often used as a portable way to encode binary data for use in networked applications. This module is able to encode and decode XDR data because it supports the external data representation (XDR) Standard. mailcap The mailcap module is used to read mailcap files and to configure how MIME-aware applications react to files with different MIME types. Note mailcap files are used to inform mail readers and Web browsers how to process files with different MIME types.
mimetypes The mimetypes module supports conversions between a filename or URL and the MIME type associated with the filename extension. Essentially, it is used to guess the MIME type associated with a file, based on its extension, as shown in Table 3.1.
Table 3.1. Some MIME Type Examples Filename Extension .html .rdf .gif MIME Type Associated text/html application/xml image/gif
quopri The quopri module performs encoding and decoding of MIME quoted printable data. This format is primarily used to encode text files. mailbox The mailbox module implements classes that allow easy and uniform access to read various mailbox formats in a UNIX system. mhlib The mhlib module provides a Python interface to access MH folders and their contents. mimify The mimify module has functions to convert and process simple and multipart mail messages to/from the MIME format. netrc The netrc module parses, processes, and encapsulates the .netrc configuration file format used by the UNIX FTP program and other FTP clients.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > Restricted Execution
CONTINUE >
Restricted Execution
Restricted Execution is the basic framework in Python that allows the segregation of trusted and untrusted code. The next modules prevent access to critical operations mostly because a program running in trusted mode can create an execution environment in which untrusted code can be executed with limited privileges. rexec The rexec module implements a basic restricted execution framework by encapsulating, in a class, the attributes that specify the capabilities for the code to execute. Code executed in this restricted environment will only have access to modules and functions that are believed to be safe. Bastion The Bastion module provides restricted access to objects. This module is able to provide a way to forbid access to certain attributes of an object.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > Multimedia
CONTINUE >
Multimedia
The next several modules implement algorithms and interfaces that are mainly useful for multimedia applications. audioop The audioop module manipulates raw audio data, such as samples and fragments. imageop The imageop module manipulates raw image data by operating on images consisting of 8- or 32-bit pixels stored in Python strings. aifc The aifc module is devoted to audio file access for AIFF and AIFC formats. This module offers support for reading and writing files in those formats. sunau The sunau module provides an interface to read and write files in the Sun AU sound format. wave The wave module provides an interface to read and write files in the WAV sound format. It doesn't support compression/decompression, but it supports mono/stereo channels. chunk The chunk module provides an interface for reading files that use EA IFF 85 data chunks. This format is used in the AIFF/AIFF-C, RMFF, and TIFF formats. colorsys
The colorsys module defines bidirectional conversions of color values between colors expressed in RGB and three other coordinate systems: YIQ, HLS, and HSV. rgbimg The rgbimg module allows Python programs to read and write SGI imglib .rgb fileswithout requiring an SGI environment. imghdr The imghdr module determines the type of an image contained in a file or byte stream. sndhdr The sndhdr module implements functions that try to identify the type of sound contained in a file.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > Cryptographic
CONTINUE >
Cryptographic
The following modules implement various algorithms of cryptographic nature. For more information about this topic, you can also check out the following Web site: http://starship.python.net/crew/amk/python/crypto.html It contains cryptographic modules written by Andrew Kuchling for reading and decrypting PGP files. md5 The md5 module is a cryptographically secure hashing algorithm that implements an interface to RSA's MD5 message digest algorithm. Based on a given string, it calculates a 128-bit message signature. sha The sha module is a message digest algorithm that implements an interface to NIST's secure hash algorithm, known as sha. This module takes a sequence of input text and generates a 160-bit hash value. mpz The mpz module implements the interface to part of the GNU multiple precision integer libraries. rotor The rotor module implements a permutation-based encryption and decryption engine. (The design is derived from the Enigma device, a machine used by the Germans to encrypt messages during WWII.)
import rotor message = raw_input("Enter the message") key = raw_input("Enter the key") newr = rotor.newrotor(key) enc = newr.encrypt(message)
>>> print "The encoded message is: ", repr(enc) >>> dec = newr.decrypt(enc) >>> print "The decoded message is: ", repr(dec)
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > UNIX Specific
CONTINUE >
UNIX Specific
This group of modules exposes interfaces to features that are specific to the UNIX environment. posix The posix module provides access to the most common POSIX system calls. Do not import this module directly; instead, I suggest that you import the os module.
pwd The pwd module provides access to the UNIX passwd (password database) file routines.
pwd.getpwnam()
grp The grp module provides access to the UNIX group database. crypt
The crypt module offers an interface to the UNIX crypt routine. This module has a hash function based on a modified DES algorithm that is used to check UNIX passwords. To encrypt:
salt consists of a two-random character seed used to initialize the algorithm. To verify:
If newpwd == crypt.crypt(passwordstring, newpwd[:2]) import getpass import pwd import crypt uname = getpass.getuser() pw = getpass.getpass() # get username from environment # get entered password
realpw = pwd.getpwnam(uname)[1] # get real password entrpw = crypt.crypt(pw, realpw[:2]) # returns an encrypted password if realpw == entrpw: # compare passwords print "Password Accepted" else: print "Get lost."
dlmodule The dlmodule module exposes an interface to call C functions in shared objects that handle dynamically linked libraries. Note that this module is not needed for dynamic loading of Python modules. The documentation says that it is a highly experimental and dangerous device for calling arbitrary C functions in arbitrary shared libraries. dbm The dbm module is a database interface that implements a simple UNIX (n)dbm library access method. dbm objects behave like dictionaries in which keys and values must contain string objects. This
module allows strings, which might encode any python objects, to be archived in indexed files. See Chapter 8 for details. gdbm The gdbm module is similar to the dbm module. However, their files are incompatible. This module provides a reinterpretation of the GNU dbm library. See Chapter 8 for details. termios The termios module provides an interface to the POSIX calls for managing the behavior of the POSIX tty. TERMIOS The TERMIOS module stores constants required while using the termios module. tty The tty module implements terminal controlling functions for switching the tty into cbreak and raw modes. pty The pty module offers utilities to handle the pseudo-terminal concept. fcntl The fcntl module performs file and I/O control on UNIX file descriptors. This module implements The fcntl() and ioctl() system calls, which can be used for file locking. pipes The pipes module offers an interface to UNIX shell pipelines. By abstracting the pipeline concept, it enables you to create and use your own pipelines. posixfile
The posixfile module provides file-like objects with support for locking. It seems that this module will become obsolete soon. resource The resource module offers mechanisms for measuring and controlling system resources used by a program. nis The nis module is a thin wrapper around Sun's NIS library. syslog The syslog module implements an interface to the UNIX syslog library routines. This module allows you to trace the activity of your programs in a way similar to many daemons running on a typical GNU/Linux system.
import syslog syslog.syslog('This script was activated') print "I am a lumberjack, and I am OK!" syslog.syslog('Shutting down script')
Use the command tail -f /var/log/messages to read what your script is writing to the log. popen2 The popen2 module allows you to create processes by running external commands and to connect their accessible streams (stdin, stdout, and stderr) using pipes.
import os,popen2 str1 = os.popen('ls','r').read() print str1 out1,in1 = popen2.popen2('cat') in1.write(str1) in1.close() str2 = out1.read() out1.close()
print str2
Note Note that as of release 2.0, functions popen2, popen3, popen4 are supported on the Windows Platform.
commands The commands module provides functions that execute external commands under UNIX by implementing wrapping functions for the os.popen() function. Those functions get a system command as a string argument and return any output generated by that command.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
UNIX, encrypting UNIX, verifying popen2 function popen3 function popen4 function pwd module syntax functions pwd.getpwnam() UNIX Specific library 2nd verifying UNIX passwords
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 3. Python Libraries > SGI IRIX Specific
CONTINUE >
gl The gl module implements an interface that provides access to the Silicon Graphics graphic library. Note that this is different for OpenGL. There is a wrapper for OpenGL called PyOpenGL. More details can be found at Chapter 14, "Python and GUIs." DEVICE The DEVICE module defines the constants that are used with the gl module. GL The GL module stores the constants that are used with the gl module. imgfile The imgfile module implements support to access SGI's imglib image files. jpeg The jpeg module provides image file access (read and write) to the JPEG compressor and decompressor format written by the Independent JPEG Group (IJG).
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > Sun OS Specific
CONTINUE >
Sun OS Specific
These modules implement interfaces that are specific to the Sun OS Operating System. sunaudiodev The sunaudiodev module implements an interface that gives you access to the Sun audio hardware. SUNAUDIODEV The SUNAUDIODEV module stores the constants that are used with the sunaudiodev module.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark 2002, O'Reilly & Associates, Inc. CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > MS Windows Specific
CONTINUE >
MS Windows Specific
The next modules define interfaces that are specific to the Microsoft Windows Operating System. msvcrt The msvcrt module implements many functions that provide access to useful routines from the Microsoft Visual C++ runtime library. winsound The winsound module implements an interface that provides access to the sound-playing environment provided by Windows Platforms.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > Macintosh Specific
CONTINUE >
Macintosh Specific
The following modules implement specific interfaces to the Macintosh Operating System. For more information about Macintosh module, take a look at the online Macintosh Library Reference at http://www.python.org/doc/mac. findertools The findertools module provides access to some of the functionality presented in the Macintosh finder. It launches, prints, copies, and moves files; it also restarts and shuts down the machine. macfs The macfs module is used to manipulate files and aliases on the Macintosh OS. macostools The macostools module implements functions for file manipulation on the Macintosh OS.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > Undocumented See All Titles Modules
CONTINUE >
Undocumented Modules
Currently, the modules listed in this section don't have any official documentation. However, you might find some information about them in this book, by browsing an updated version of the online library reference, or by checking some other Web site. Frameworks The next modules represent some Python frameworks that don't have any official documentation yet. Tkinter This module allows you to create GUIs (graphical user interfaces) because it implements an interface to the Tcl/Tk windowing libraries (see Chapter 15, "Tkinter," for details). Tkdnd This module provides drag-and-drop support for Tkinter. test This package is responsible for the regression-testing framework. Miscellaneous Useful Utilities At this time this book went to press, the following modules didn't have any official documentation.
dircmp
The ihooks module is a framework that manages the co-existence of different import routines. Platform Specific Modules
These are implementation details of the os module. dospath, macpath, posixpath, ntpath These modules are for their platforms what the os.path module is for the UNIX platform. They can all be used by any platform in order to handle pathnames of different platforms. Multimedia At the time this book went to press, the following modules didn't have any official documentation.
Obsolete The following modules became obsolete as of release 1.6: stdwin, soundex, cml, cmpcache, dircache, dump, find, grep, packmail, poly, zmod, strop, util, and whatsound. Note that release 2.0 hasn't made any module obsolete. All modules that were replaced were moved to the lib-old subdirectory of the distribution. That list, includes: cmp, cmpcache, dircmp, dump, find, grep, packmail, poly, util, whatsound, zmod.
ni
Before version 1.5a4, the ni module was used to support import package statements.
dump
The dump module prints the definition of a variable. Note that this module can be substituted for the pickle module.
>>> import dump >>> var = (10, 20, 30, 40) >>> dump.dumpvar("newvar", var) newvar = (10, 20, 30, 40)
Extension Modules The following modules are obsolete tools to support GUI implementations. stdwin This module provides an interface to the obsolete STDWIN. STDWIN is an unsupported platform-independent GUI interface that was replaced by Tkinter. stdwinevents Interacts with the stdwin module by providing piping services. New Modules on Python 2.0 Next, you a have a list of new modules that were introduced to Python recently. As always, I suggest you take a look at the 2.0 documentation for details about any given module. atexit Registers functions to be called when Python exits. If you already use the function sys.exitfunc(), you should change your code to import atexit, and call the function atexit.register(), passing as an argument the function that you want to call on exit. codecs Provides support (base classes) for Unicode encoders and decoders, and provides access to Python's codec registry. You can use the functions provided by this module to search for existing encodings, or to register new ones. Most frequently, you will adhere to the function codecs.lookup(encoding), which returns a 4function tuple: (encoder, decoder, stream_reader, stream_writer). This module along with the unicodedata module was added as part of the new Unicode support to Python 2.0. The condec class defines the interface for stateless encoders and decoders. The following functions and classes are also available in this module. codec.encode() Takes a Unicode string, and returns a 2-tuple (8-bit-string, length). The length part of the tuple shows how much of the Unicode string was converted. codec.decode() Takes an 8-bit string, and returns a 2-tuple (ustring, length). The length part of the tuple shows how much of the 8-bit string was consumed. codecs.stream_reader(file_object) This is a class that supports decoding input from a stream. Objects created with this class carry the read(), readline(), and readlines() methods, which allow you to take the given
encoding of the object, and read as a Unicode string. codecs.stream_writer(file_object) This is a class that supports encoding output to a stream. Objects created with this class carry the write() and writelines() methods, which allow you to pass Unicode string to the object, and let the object translate them to the given encoding on output. unicodedata This module provides access to the Unicode 3.0 database of character properties. The following functions are available: unicodedata.category(u'P') returns the 2-character string 'Lu', the 'L'denoting it's a letter, and 'u'meaning that it's uppercase. unicodedata.bidirectional(u'\ x0660') returns 'AN', meaning that U+0660 is an Arabic number. encodings This is a package that supplies a wide collection of standard codecs. Currently, only the new Unicode support is provided. distutils Package of tools for distributing Python modules. filecmp This module comes into place of both the cmp.py, the cmpcache.py and dircmp.py modules. gettext Provides an interface to the GNU gettext message catalog library in order to supply internationalization (I18N) and localization (L10N) support for Python programs. imputil This module is an alternative API for writing customized import hooks in a simpler way. It is similar to the existing ihooks module. linuxaudiodev Provides audio for any platform that supports the Open Sound System (OSS). Most often, it is used to support the /dev/audio device on Linux boxes. This module is identical to the already existing sunaudiodev module. mmap This module works on both Windows and Unix to treat a file as a memory buffer, making it possible to map a file directly into memory, and make it behave like a mutable string. pyexpat This module is an interface to the Expat XML parser. robotparser Initially at Tools/webchecker/, this module parses a
robots.txt file, which is used for writing web spiders. sre This module is a new implementation for handling regular expressions. Although it is still very raw, its features include: faster mechanism, and support to unicode. The idea of the development team is to reimplement the re module using sre (without making changes to the re API). tabnanny Originally at Tools/scripts/, this module checks Python sources for tab-width dependance (ambiguous indentation). urllib2 This module is an experimental version of urllib, which will bring new and enhanced features, but will be incompatible with the current version. UserString This module exposes a base class for deriving objects from the string type. xml This package covers the whole-new XML support and it is organized in three subpackages: xml.dom, xml.sax, and xml.parsers. webbrowser A module that provides a platform independent API to launch a web browser on a specific URL. _winreg This module works as an interface to the Windows registry. It contains an enhanced set of functions that has been part of PythonWin since 1995. zipfile This module reads and writes zip-format archives (the format produced by PKZIP and zip applications. Not the one produced by the gzip program!).
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 3. Python Libraries > Summary
CONTINUE >
Summary
Python's standard distribution is shipped with a rich set of libraries (also known as modules). This chapter introduces you to the practical side of several modules'utilization. The following items are groups that organize all the modules that are mentioned in this chapter. Python Services The modules from this group provide access to services related to the interpreter and to Python's environment. The String Group This group is responsible for many kinds of string services available. Its modules provide access to several types of string manipulation operations. Miscellaneous This group handles many functions that are available for all Python versions, such as mathematical operations and randomizing functions. Generic Operational System This group of services provides interfaces to operating system features that you can use in almost every platform. Optional Operational System This set of modules implements interfaces to optional operational system features. Debugger The pdb module defines an interactive source code debugger for Python programs. Profiler
The profiler module is a code execution profiler. Internet Protocol and Support These are the modules that implement internet protocols and support for related technology. Internet Data Handling This group covers modules that support encoding and decoding of data handling formats and that are largely used in Internet applications. Restricted Execution These modules prevent access to critical operations. Multimedia This group of modules implements algorithms and interfaces that are mainly useful for multimedia applications. Cryptographic These modules implement various algorithms of cryptographic nature. OS Specific (UNIX, SGI IRIX, SUN OS, MS Windows, and Macintosh) These groups of modules expose interfaces to features that are specific to the OS environment of each one of them. Undocumented Modules This group contains the modules that currently don't have any official documentation. New Modules in Python 2.0 These are the new modules that will be part of the next release of Python.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
CONTINUE >
Web Development > Python Developer's Handbook > 4. Exception Handling > Exception Handling
CONTINUE >
Exception Handling
Exceptions are mostly used for error handling and event notification. They work by breaking the regular flow of a program and jumping to a special set of statements that handle the exception case. Python has many standard exceptions, which are exceptions already built into the language. Python also supports user-defined exceptions, which are exceptions created by users. The provided exceptions are almost no different from user-defined exceptionsthe only difference is that they are defined in one of the files in the standard library (exceptions.py). Any unexpected program behavior drives the interpreter to raise an exception. Many scenarios can help an exception to be raised, such as dividing a number by zero or reading from a nonexistent file. Note that the programmer can also manually raise exceptions with the raise statement. The default behavior of Python, when it encounters unhandled exceptions, is to terminate the program and to display a traceback message that describes the error condition. My goal in this chapter is to show you how to handle those exceptions. If you don't handle exceptions in your program, Python's interpreter returns a traceback message that shows the error message, the exception type, the function that contains the error, and the line of code that has caused the error. Hence, a complete history of what has caused the error is provided. So that you can start learning how Python raises and handles exceptions, I will define the following example:
Note that "c" is not part of the a dictionary. Therefore, Python raises an exception that displays the following traceback message.
Traceback (innermost last): File "<stdin>", line 1, in ? File "<stdin>", line 2, in returnelement KeyError: c
The last line of the traceback message tells us what exception was raised and what element has caused the exception to be triggered. If we run the previous code in the interpreter, the File clause is set to "<stdin>" by default because the code lines come from the keyboard and not from a file. However, if we run the code from an external file, the filename becomes part of the File clause. It is also worth mentioning that the line numbers are relative to the statement where the error occurred when the code was entered interactively. So, we get line 2 in the traceback because the exception occurred on the second line of the function, which was treated as a single statement. The outermost part of the trace says line 1 because the call to returnelement was treated as a one-line statement. Next to the filename, we have a line number, which is the line in which the error has been triggered. Next to the line number is the name of the function that caused the error. Tip By handling exceptions, you can save a lot of time while testing your code.
Exceptions can be handled by using either try/except or try/finally statements. The difference between them is that an except clause is only executed when an exception is raised, and a finally clause is always executed; it doesn't matter whether an exception is raised or not. Also, the try/finally block doesn't catch the exception like try/except can. Next is the standard structure for a try/except statement:
try: <statements>
except [<exception_name> [, <instance_variable>]]: <exception handling statements> [else: <statements executed only when no exception is raised>]
The else block must be inserted after the last exception block, and it is only executed when the try block doesn't raise any errors. In order to handle multiple exceptions, you can use multiple except clauses for the same try block. The next example raises an error message whenever it can't find a given element.
>>> name = ["Andre","Renata","Joao","Rebecca"] >>> def getname(order): try: if order < 10: data = name[order] else: file = open("names.txt") data = file.readline() file.close() return data except IndexError: print "This name is not in the list." except IOError: print "The file names.txt does not exist." >>> getname(0) "Andre" >>> getname(8) "This name is not in the list." >>> getname(20) "The file names.txt does not exist."
Python syntax also enables you to use a single except clause that handles all exceptions. The general syntax for the except clause for handling all exceptions is to not specify any exception types at all, such as
Next, you have the syntax and an example for handling multiple exception types.
except (exception1, exception 2, exception 3)[, variable]: >>> name = ["Andre","Renata","Joao","Rebecca"] >>> def getname(order): try: if order < 10: data = name[order] else: file = open("names.txt") data = file.readline() file.close() return data except (IndexError, IOError): print "Data not available." >>> getname(8) "Data not available." >>> getname(20) "Data not available."
You can also use try/except statements to ignore exceptions. The next structure uses a pass statement to ignore an exception whenever it gets raised. However, note that if an exception is raised, all the remaining statements in the try block will not be executed.
In the next example, we use exceptions not to catch and handle an unexpected error, but to ignore errors that we know might happen when the code is running. As you can see, an exception is raised every time you try to convert a text string into a float number in line 6. However the pass statement in line 8 simply ignores the problem.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
import string list = ["1","3","Monkey","Parrot","10"] total = 0 for z in list: try: total = total + string.atof(z) except: pass print total
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 4. Exception Handling > Standard Exceptions (Getting Help from Other Modules)
CONTINUE >
Note that these objects only work when called from within an except clause.>>> import sys >>> try: 1/0 except: print sys.exc_type, ":", sys.exc_value exceptions.ZeroDivisionError : integer division or modulo
>>> import sys >>> try: 1/0 except: info = sys.exc_info() exc_type = info[0] exc_value = info[1] exc_traceback = info[2] print exc_type, ":", exc_value exceptions.ZeroDivisionError : integer division or modulo
A more compact way to assign the values to the variables is by using sequence unpacking, as is demonstrated by the following:
The Python module called traceback, which is part of the standard Python library, helps you to debug the call stack after an exception has been raised.
>>> import traceback >>> try: 1/0 except: print "The next lines show the traceback message" print "-----------------------------------------" traceback.print_exc() print "-----------------------------------------" The next lines show the traceback message ----------------------------------------Traceback (innermost last): File "<stdin>", line 2, in ? ZeroDivisionError: integer division or modulo -----------------------------------------
The previous program chooses the right time to display the traceback message by using the traceback.print_exc() function (line 7). You can also extract the traceback information by parsing the results of sys.exc_traceback.
>>> import sys, traceback >>> try: result = 1/0 except: trace = traceback.extract_tb(sys.exc_traceback) for filename, lineno,function,message in trace: print "File name: ", filename print "Error message: ", message print "Line: ", lineno print "Function: ", function
By using the objects sys.last_type, sys.last_value, and sys.last_traceback, you can get the details about the last uncaught exception. When I say that, I mean the last exception that had a traceback message displayed.
>>> import sys >>> x = 0 >>> 1 / x Traceback (innermost last): File "<stdin>", line 1, in ? ZeroDivisionError: integer division or modulo >>> 1.0 / 10 0.1 >>> print sys.last_type exceptions.ZeroDivisionError >>> print sys.last_value integer division or modulo
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
tradeback module 2nd uncaught exceptions values sys module objects 2nd sys.exe_traceback 2nd sys.exe_type sys.exe_value
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 4. Exception Handling > Raising Exceptions
CONTINUE >
Raising Exceptions
There are several ways to raise exceptions. You can either raise your own exceptions or Python standard exceptions by using any of the four techniques listed as follows:
q
raise class raise exception, argument raise exception, (argument1, argument2, ) raise exception (argument1, argument2, )
Note that the second and third forms of raising exceptions use the old form of passing arguments with the exception. I recommended using only the first and fourth forms. Passing None, as the second argument, to the raise statement is equivalent to omitting it. raise class, None is equivalent to raise class() Check the following cases.
In the previous lines, the examples use a standard exception called IndexError. However, you can raise any one of the supported built-in exceptions. Look at another example that uses a different exception:
op = raw_input("Enter an operator: ") op1 = input("Enter first operand: ") op2 = input("Enter second operand: ") if op == "+": print op1 + op2 else: raise RuntimeError("I don't know this command")
In the next chapter, after learning how you can handle classes, you will be able to easily understand this next example. For the present time, take a deep breath and just have some fun. This example raises an exception that blocks your access to nonexistent members of the c class.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
>>> class c: def __init__(self, name): self.name = name def __getattr__(self, attr): if attr <> "name": raise AttributeError >>> a = c("Andre") >>> a.name 'Andre' >>> a.age
The following traceback message is generated after running the command located at line 11.
Traceback (innermost last): File "<stdin>", line 1, in ? File "<stdin>", line 6, in __getattr__ AttributeError
As you can see, line 5 checks the name of the attribute that is being passed to the method. That makes the exception in line 6 to always be raised when the attribute name is not "name". However, note that if you assign something to a.age, as demonstrated next, getting the value of
a.age will no longer cause the error. To handle that, you would need to write a code to deal with the __setattr__ method, but that would be another example.
Raising an Exception to Leave the Interpreter Raising the SystemExit exception is a generic way to leave the Python interpreter.
C:\Program Files\Python>python Python 1.5.2 (#0, Apr 13 1999, 10:51:12) [MSC 32 bit (Intel)] on win32 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam >>> raise SystemExit C:\Program Files\Python>
The next example demonstrates how you can trap the SystemExit exception.
>>> try: raise SystemExit except SystemExit: print "Sorry. You can not leave." Sorry. You can not leave.
The sys.exit() function raises an exception SystemExit that, if not caught, causes the thread to exit silently.
>>> import sys >>> try: sys.exit() except SystemExit: print "I have already told you. You can not leave."
Raising an Exception to Leave Nested Loops Sometimes you are so deeply involved in your data structures that you only want to get out of all your nested loops quickly. Normally, you would have to use break for each level of interaction. The next example demonstrates how to handle this situation by using exceptions.
ExitLoop = "ExitLoop" try: i=1 while i < 10: for j in xrange(1,5): print i,j if (i==2) and (j==3): raise ExitLoop i = i + 1 except ExitLoop: print "i=2 and j=3 is a special case."
Raising String Exceptions Older versions used to support only strings for both Python standard exceptions and user-defined exceptions.
Nowadays, Python supports both strings and exception classes. There are costs to using class exceptions because they must be instantiated to be caught. Note that most people don't use exceptions to control the flow of their program, so they don't occur much. However, classes give you much more flexibility to generalize the type of error that you want to catch. Tip Try to define your own exceptions as classes instead of strings.
Instancing an Exception Class Every time an exception is raised, an instance of the exception class is created. The next syntax demonstrates how to catch a class instance in your program.
The instance variable is an instance of the raised exception. Therefore, it inherits attributes from the exception class. Each instance has an attribute called args that returns the error string in a tuple format.
>>> try: a = [1,2] print a[4] except IndexError, b: print b.args ('list index out of range',)
Particularly, the EnvironmentError exception has a 2-tuple or 3-tuple structure that can be
>>> try: file = open("Parrot") except EnvironmentError, b: print b.args (2, 'No such file or directory')
When the instance belongs to a SyntaxError class exception, four special attributes are also returned: filename, lineno, offset, and text.
>>> try: a = "x===10" exec a except SyntaxError, b: print b.args ('invalid syntax', (None, 1, 4, 'x===10'))
Note Modules are parsed before being run, so syntax errors in a file can't be caught by try/except blocks that surround the error. You can catch it from the bit of code that imported the module, however.
Debugging Your Code Exceptions are very good for helping to debug your code. You can use the assert command to raise a debugging exception that transports a message to your exception handling code. The syntax is assert <TestStatement> [,argument] This command raises an AssertionError exception whenever <TestStatement> evaluates to false.
For example
>>> def divide (a,b): assert b != 0, "Can't divide by zero" return a/b >>> >>> divide(10,0) Traceback (innermost last): File "<stdin>", line 1, in ? File "<stdin>", line 2, in divide AssertionError: Can't divide by zero
__debug__ is a built-in name and has its value set to true by default. To set __debug__ to false, it is necessary to change the interpreter to run in optimized mode. Tip Calling the interpreter with the -O option activates the optimized mode.
c:\>python -O
Currently, Python's command-line option -X turns all standard exceptions into strings. Version 1.6 is expected to have this option removed, and make all standard exceptions into classes. User code that deals with string exceptions will still be supported, but not encouraged. See Chapter 17, "Development Tools," for more details about other command-line options that you can transport as configuration parameters to the interpreter.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
instances class catching instancing exception classes 2nd interpreters raising exceptions to leave modes optimized modules parsing optimized mode options [nd]O [nd]X parsing modules raise class() function raise statement raising exceptions 2nd 3rd 4th 5th source code debugging exceptions statements raise try/except string exceptions raising syntax commands assert command SyntaxError exception sys.exit() function SystemExit exception 2nd try/except statement variables instance
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 4. Exception Handling > Catching Exceptions
CONTINUE >
Catching Exceptions
Look at an example that shows how to catch a specific exception message.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
zerodivision(x): return 1/x test(x): try: print zerodivision(x) except ZeroDivisionError: print "You can not divide this number by Zero"
In line 7, we are specifying the exact exception type that we want to catch. You can also replace lines 7 and 8 from the previous example with the text from the next snippet. The difference is that this new scenario also shows the error message provided by the interpreter.
except ZeroDivisionError, error_message: print "You can't divide this number by Zero - ", error_message
Besides catching Python standard exceptions, it is also possible to catch user-defined, non-Error exceptions.
found = "Item found" def searcher(arg): if arg == 1: print "executing the routine." else: raise found try: searcher() except found: print "The routine has failed."
The next example re-raises an exception because the win32pipe module is not present in the system.
>>> try: import win32pipe except: raise ImportError, "The module is not available" Traceback (innermost last): File "<stdin>", line 4, in ? ImportError: The module is not available
The next example actually shows how to raise the same exception (provided the exception is a class exception). This type of implementation doesn't require you to know the name of the exception being raised.
>>> import sys >>> try: import win32pipe except: raise sys.exc_value Traceback (innermost last): File "<stdin>", line 4, in ? ImportError: No module named win32pipe
The following code catches an IOError exception and raises a SystemExit exception by using the sys.exit() function.
>>> import sys >>> try: file = open("file.txt") except IOError: print "Error opening file for reading" sys.exit(0)
Catching Standard Errors The errno module makes available the standard errno system symbols, which can be used to check the
meaning of an error.
>>> import errno >>> try: >>> file = open("test.py") >>> except IOError, (errcode, errmsg): >>> if errcode == errno.ENOENT: >>> print "File does not exist!" >>>
>>> import errno >>> dir(errno) ['E2BIG', 'EACCES', 'EADDRINUSE', 'EADDRNOTAVAIL', EAFNOSUPPORT', 'EAGAIN', 'EALREADY', 'EBADF', 'EBUSY', 'ECHILD', 'ECONNABORTED', 'ECONNREFUSED', 'ECONNRESET', 'EDEADLK', 'EDEADLOCK', 'EDESTADDRREQ', 'EDOM', 'EDQUOT', 'EEXIST', 'EFAULT', 'EFBIG', 'EHOSTDOWN', 'EHOSTUNREACH', 'EILSEQ', 'EINPROGRESS', 'EINTR', 'EINVAL', 'EIO', 'EISCONN', 'EISDIR', 'ELOOP', 'EMFILE', 'EMLINK', 'EMSGSIZE', 'ENAMETOOLONG', 'ENETDOWN', 'ENETRESET', 'ENETUNREACH', 'ENFILE', 'ENOBUFS', 'ENODEV', 'ENOENT', 'ENOEXEC', 'ENOLCK', 'ENOMEM', 'ENOPROTOOPT', 'ENOSPC', 'ENOSYS', 'ENOTCONN', 'ENOTDIR', 'ENOTEMPTY', 'ENOTSOCK', 'ENOTTY', 'ENXIO', 'EOPNOTSUPP', 'EPERM', 'EPFNOSUPPORT', 'EPIPE', 'EPROTONOSUPPORT', 'EPROTOTYPE', 'ERANGE', 'EREMOTE', 'EROFS', 'ESHUTDOWN', 'ESOCKTNOSUPPORT', 'ESPIPE', 'ESRCH', 'ESTALE', 'ETIMEDOUT', 'ETOOMANYREFS', 'EUSERS', 'EWOULDBLOCK', 'EXDEV', 'WSABASEERR', 'WSAEACCES', 'WSAEADDRINUSE', 'WSAEADDRNOTAVAIL', 'WSAEAFNOSUPPORT', 'WSAEALREADY', 'WSAEBADF', 'WSAECONNABORTED', 'WSAECONNREFUSED', 'WSAECONNRESET', 'WSAEDESTADDRREQ', 'WSAEDISCON', 'WSAEDQUOT', 'WSAEFAULT', 'WSAEHOSTDOWN', 'WSAEHOSTUNREACH', 'WSAEINPROGRESS', 'WSAEINTR', 'WSAEINVAL', 'WSAEISCONN', 'WSAELOOP', 'WSAEMFILE', 'WSAEMSGSIZE', 'WSAENAMETOOLONG', 'WSAENETDOWN', 'WSAENETRESET', 'WSAENETUNREACH', 'WSAENOBUFS', 'WSAENOPROTOOPT', 'WSAENOTCONN', 'WSAENOTEMPTY', 'WSAENOTSOCK', 'WSAEOPNOTSUPP', 'WSAEPFNOSUPPORT', 'WSAEPROCLIM', 'WSAEPROTONOSUPPORT', 'WSAEPROTOTYPE', 'WSAEREMOTE', 'WSAESHUTDOWN', 'WSAESOCKTNOSUPPORT', 'WSAESTALE', 'WSAETIMEDOUT', 'WSAETOOMANYREFS', 'WSAEUSERS', 'WSAEWOULDBLOCK', 'WSANOTINITIALISED', 'WSASYSNOTREADY', 'WSAVERNOTSUPPORTED', '__doc__', '__name__', 'errorcode']
Use the os.strerror() function to \ retrieve the system message associated to a specific error symbol.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 4. Exception Handling > try/finally
CONTINUE >
try/finally
The try/finally statement is good for clean-up actions. The code in the finally block is always executed, no matter whether the try block fails or not.
1: try: 2: f = open("c:\\autoexec.bat") 3: lines = f.readlines() 4: finally: 5: f.close() # it is always executed 6: print "It is done" # it is executed on success only
The previous piece of code opens a file and tries to read its lines. It is not necessary to check whether the process raises an error in order to close the file because the close function in line 5 is always executed, no matter what. Now, take a look at line 6. The print statement is only executed when the finally block is bypassed because when an error is raised, the finally block is executed and the program is terminated immediately afterwards if the exception is not handled, leaving the exception unhandled. Tip finally and except clauses cannot be used together along with a unique try clause.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 4. Exception Handling > Creating User-defined Exceptions
CONTINUE >
import exceptions class ConfigError (exceptions.Exception): def __init__(self, arg=None): self.args = arg try: raise ConfigError("Bad hostname") except ConfigError, e: print e.args hostname
The import statement from the previous example isn't really necessary because the exceptions module contents are automatically imported by the interpreter. Remember that you can't use the prefix "exceptions" because the exceptions module is not available in the __main__ namespace until you import it. The next example uses the class created in the previous example as a base class to create a new class.
def printargs(self): print self.args >>> try: raise TimeoutError, "Timeout" except TimeoutError, e: e.printargs() Timeout
As you could see, just by overriding the __init__ method, you are able to create your own exception classes. You can also change the output of a traceback message by overwriting the __str__ method.
>>> class ConfigError(Exception): def __init__(self, args=None): self.args = args def __str__(self): return "\ nError in the module configuration\ n" + } `self.args` + "\ n" >>> raise ConfigError, "bad hostname" Traceback (innermost last): File "<stdin>", line 1, in ? __main__.ConfigError Error in the module configuration bad hostname
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 4. Exception Handling > The Standard Exception Hierarchy
CONTINUE >
Table 4.1. The Exception Class Hierarchy Exception SystemExit StandardError KeyboardInterrupt ImportError EnvironmentError IOError OSError EOFError
RuntimeError NotImplementedError NameError UnboundLocalError AttributeError SyntaxError TypeError AssertionError LookupError IndexError KeyError ArithmeticError OverflowError ZeroDivisionError FloatingPointError ValueError SystemError MemoryError
Exception This is the root class. All exception classes are subclasses of this base class. Every user exception class should be derived from this class too. SystemExit This is an exception because it isn't really an error message. Instead, it
can be used to exit a program. The important thing is that this exception doesn't return any traceback message. StandardError It is the base class for all errors (except for SystemExit, of course). KeyboardInterrupt It is raised when an interrupt key, such as CTRL+C, is pressed. ImportError It is raised when Python cannot find a module to import. EnvironmentError This is the base class for errors that occur outside the Python environment. The IOError and OSError classes subclass it. IOError It is raised by I/O operation errors. OSError This one is raised by operating system errors, usually generated by the os module. EOFError Exception raised when an End-of-File (EOF) error occurs. RuntimeError This is a special type of exception raised by errors that aren't covered by any of the other exceptions. NotImplementedError Methods or functions that aren't implemented should raise this exception.
NameError It is raised when the interpreter finds a name that is neither in the local nor in the global namespace. UnboundLocalError This is a new exception that was created for version 1.6. It subclasses the NameError exception, raising an error when a local variable is undefined. AttributeError It is raised by attribute reference and attribute assignment kinds
of errors. Note that starting with version 1.6, this exception will have a more friendly error message, which is expected to break some code that assumes the message to be exactly equivalent to the attribute name. SyntaxError It is raised by syntax errors. TypeError This exception is raised when you try to apply a function operation to an object of inappropriate type. AssertionError This kind of exception is raised when an assert statement fails by evaluating to false. LookupError This is the base class for indexing and key errors. The IndexError and KeyError classes subclass it. IndexError It is raised by "sequence out of range" errors. KeyError It is raised when a key is not found in a dictionary. ArithmeticError This is the base class for arithmetic errors. The classes OverflowError, ZeroDivisionError, and FloatingPointError subclass it. OverflowError This exception is raised when the result is so large that it makes the operation overflow. ZeroDivisionError It is raised when an operation that tries to divide a number by zero is performed. FloatingPointError This exception is raised by floating-point operation errors. Note that on Linux systems, you are required to enable the SIGFPE handling with the fpectl module to use this exception. ValueError This one is raised when you try to perform an action using the right type but the wrong value. SystemError It is raised if a Python's interpreter internal error takes place. MemoryError This exception is raised by a recoverable out-of-memory error.
As exception classes are grouped within other exception classes (known as base classes), it becomes much easier to catch several different types of errors/exceptions by using just one except clause. Base classes are never raised, but can be used to catch up errors. The next scenario shows how to cover multiple exceptions by declaring only the base class exception.
Based on these structures, we get the following error messages when we try any out-of-range type of operations.
>>> dict[3] Traceback (innermost last): File "<stdin>", line 1, in ? KeyError: 3 >>> list[8] Traceback (innermost last): File "<stdin>", line 1, in ? IndexError: list index out of range
The following example is able to catch both IndexError and KeyError exceptions.
>>> def getelement(element): >>> try: >>> if element < 10: >>> print dict[element] >>> else: >>> print list[element] >>> except LookupError: >>> print "Sorry. This element does not exist" >>> getelement(1) First Element >>> getelement(20) Sorry. This element does not exist
Now, let's talk about release 2.0. Check the next code.
The previous code raises an exception on the print statement in both 1.5.2 and 2.0 release. However, in 1.5.2 a NameError exception is raised, while in 2.0 a new exception is raised. This new exception is called UnboundLocalError, which is a subclass of the NameError exception. Talking about new exceptions, the Python 2.0 release comes with two more brand-new exceptions. They are called TabError and IndentationError, and they are subclasses of the SyntaxError exception.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 4. Exception Handling > Summary
CONTINUE >
Summary
Python exceptions are mostly used for error handling and event notification. If you don't handle exceptions in your program, Python's interpreter returns traceback messages. Python comes filled with many built-in exceptions. All these exceptions are part of the exceptions module, which is always loaded prior to any program execution. Exceptions can be handled by using either try/except or try/finally statements. The difference between them is that an except clause is only executed when an exception is raised, and a finally clause is always executed, no matter whether an exception is raised or not. The try/finally statement is good for clean-up actions, but remember that it doesn't actually catch the exceptions. Python supports both strings and exception classes. As exception classes are grouped within other exception classes (known as base classes), it becomes much easier to catch several different types of errors/exceptions by using just one except clause. Base classes are never raised, but can be used to catch up errors. You can either raise your own exceptions or use Python standard exceptions. Python allows you to create your own exceptions by subclassing any standard Python exception. Exceptions can be raised for several purposes (for example, exit the interpreter, leaving nested loops, and so on). Every time an exception is raised, an instance of the exception class is created. The assert command helps debug your code by raising a debugging exception. Besides the exceptions module, the sys, the errno, and the traceback modules also offer you some advanced functionality to handle exceptions.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark 2002, O'Reilly & Associates, Inc. CONTINUE >
Web Development > Python Developer's Handbook > 4. Exception Handling > Code Examples
CONTINUE >
Code Examples
This first example returns the square root of a given input value. If the input value is negative or if it is a character, two traceback messages are displayed.
Listing 4.1 Square root (File squareroot.py)
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34:
### # Program: Square root # Author: Andre S Lessa ### ### import modules import sys, traceback, math try: n = float(raw_input("Please, enter a number: ")) print "The sqrt of %f is %f" % (n, math.sqrt(n)) except (ValueError, TypeError, OverflowError): print "-----------------------------------------" print "This is the standard traceback message:" print "" traceback.print_exc() print "-----------------------------------------" print "This is the customized traceback message:" print "" info = sys.exc_info() exc_type = info[0] exc_value = info[1] exc_traceback = info[2] trace print print print print print print = traceback.extract_tb(sys.exc_traceback) "Exception Type: ", exc_type "Error Message: ", exc_value "File name: ", trace[0][0] "Error message: ", trace[0][1] "Line: ", trace[0][2] "Function: ", trace[0][3]
35: else: 36: print "Everything went just fine." The except clause in line 14 covers ValueError, OverflowError, and TypeError exceptions. The else clause in line 35 is only executed when no exception is raised. The next lines show the two traceback messages that are displayed by this program: Python standard traceback message and a customized version.
C:\python> s:\python\squareroot.py Please, enter a number: i ----------------------------------------This is the standard traceback message: Traceback (innermost last): File "s:\python\squareroot.py", line 11, in ? n = float(raw_input("Please, enter a number: ")) ValueError: invalid literal for float(): i ----------------------------------------This is the customized traceback message: Exception Type: Error Message: File name: Error message: Line: Function: exceptions.ValueError invalid literal for float(): i s:\python\squareroot.py 11 ? n = float(raw_input("Please, enter a number: "))
This example uses multiple except clauses (lines 17 and 20). It also takes advantage of the assert command to raise a debug exception (line 15).
Listing 4.2 Internet country codes (File countrycode.py)
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
### # Program: Country code # Author: Andre S Lessa ### ### import modules import sys, string matrix = { "brazil":"br","france":"fr","argentina":"ar","usa":"us"}
11: 12: def getcode(country): 13: try: 14: data = matrix[string.lower(country)] 15: assert data != "br", "You cannot select this country " + } "for this action!" 16: return data 17: except KeyError: 18: print sys.exc_type, ":", "%s is not in the list." % } sys.exc_value 19: print 20: except AssertionError, b: 21: print b 22: print 23: 24: while 1: 25: country = raw_input("Enter the country name or press x to exit: ") 26: if country == "x": 27: break 28: code = getcode(country) 29: if code != None: 30: print "%s's country code is %s" % (country, code) 31: print The following screen dump shows the execution of this program. Note that the program doesn't end after an exception has been raised.
C:\>python s:\python\ countrycode.py Enter the country name or press x to exit: Mexico exceptions.KeyError : mexico is not in the list. Enter the country name or press x to exit: USA USA's country code is us Enter the country name or press x to exit: Brazil You cannot select this country for this action! Enter the country name or press x to exit: Argentina Argentina's country code is ar Enter the country name or press x to exit: x C:\Python>
See more exception handling cases in the final section of the next chapter.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark 2002, O'Reilly & Associates, Inc. CONTINUE >
CONTINUE >
Web Development > Python Developer's Handbook > 5. Object-Oriented Programming > Object-Oriented Programming
CONTINUE >
Object-Oriented Programming
Python uses the traditional class architecture for object-oriented programming (OOP). The object-oriented model adopted by Python
q
Promotes modular design Promotes and facilitates Python software reusability Uses notions of real-world objects to develop programs Results in better quality software (but, of course, you can write bad code with any paradigm)
Object-oriented programming promotes data abstraction, information hiding, encapsulation, and modular programming. Saying that OOP promotes data abstraction means that we define the functions that operate on the data. The ideal scenario provides encapsulated data that can be accessible only through the class methods. However, in Python, we cannot totally block the programmer from accessing the information that is stored inside a class. Encapsulation, Inheritance, and Polymorphism are the most important thoughts provided by OOP. Python doesn't strictly follow the standard concepts, but you will see how far it goes. Encapsulation Data can only be accessed or manipulated by means of a set of interface functions. Encapsulation of data enables information hiding. Python provides encapsulation through conventions rather than strictly enforcing it, which can be preferable. Inheritance With inheritance, the derived class (also known as subclass, descendant, or child class) inherits the data members and class methods of its base (parent) class. Polymorphism It enables a function to have several different kinds of interfaces. Depending on the parameters used by the caller, the class knows which interface should be used. Python achieves this through its dynamic typing and late binding.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 5. Object-Oriented Programming > An Introduction to Python OOP
CONTINUE >
>>> class c: def __init__(self, value=None): self.name = value >>> obj = c() >>> obj.name = "Andre"
The identity is the memory location allocated for the object. It can be identified by using the id() function.
The object type is the object's internal representation. It defines the supported methods and operation for each object. You can use the type() function in order to find out the type of a specific object.
While we're talking about object types, let's take a quick break from the whole class issue and examine the types for Python objects defined in extension modules, which do not necessarily act like classes. Table 5.1 lists all Python built-in object types defined by the types module. Note that almost all the types shown in this table are unrelated to Python classes.
Table 5.1. Built-In Object Types Defined by the types Module Built-In Object Type NoneType IntType LongType FloatType ComplexType StringType ListType TupleType XrangeType DictType BuiltinFunctionType BuiltinMethodType Description the None (null) object integer arbitrary precision integer floating point complex number list of characters list tuple returned by xrange() dictionary built-in functions built-in methods
FuntionType ClassType InstanceType MethodType UnboundMethodType ModuleType FileType CodeType* FrameType* TracebackType* SliceType* EllipsisType*
user-defined function class object/definition class object instance/class instance bound class method unbound class method module file raw byte-compiled code represent execution frame stacks the traceback information of an exception generated by extended slices it is used in extended slices
*The checked types indicate internal Python objects that can be exposed to the user.
The attributes and methods of an object are bound properties that must be accessed by putting a dot (.) after the object name.
The string "Andre" is the value assigned to the name attribute of the object obj.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
object-oriented (OOP) 2nd 3rd properties attributes identity methods object type 2nd value SliceType object type StringType object type TracebackType object type TupleType object type types module built-in object types UnboundMethodType object type value property XrangeType object type
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 5. Object-Oriented Programming > Python Classes and Instances
CONTINUE >
The class statements section contains any valid Python statement that defines class constants or class methods. Note that the contents of the variable namespace formed by executing the commands in the class statement make up the class dictionary. Two ways to create classes are
q
You can create a new class that inherits properties of other classes. This is called subclassing, and you will learn more about it later in this chapter.
A class definition starts at the keyword class and ends at the last line of the indented block of code that goes underneath. Methods and class constants define a class namespace. Usually, a class has several methods, and they must all start with the keyword def. Tip Methods are how to call functions in a class.
All methods have the additional argument self as the first argument in the method headerThe convention is to call it self because it could be any other name. Python's self argument is similar to the this keyword in C++. Its function is to transport a reference of the object in a way that when a method is called, it knows which object should be used.
>>> class a: def __init__(self): print self >>> b = a() >>> b <__main__.a instance at 795420>
In order to reference an attribute within a class, you need to use either self.attribute or classname.attribute. Note that the self.attribute syntax is to remove ambiguities between instance variables and function local variables. Also, self.attribute and classname.attribute are different. The second sets class attributes, which will affect all instances of the class.
To reference an attribute while using a class instance, you have to use instancename.attribute.
>>> obj.name
A class can also contain class variable assignments. These variables are shared by all the class instances. Class variables are useful when the assignment of default values to instances is required. Class variables do not have the self. prefix. For example
Note that in the previous example, we had to use Student.default_age instead of using only default_age because the global namespace for a method is the module in which it was definednot the class namespace. The next example creates an instance variable that has the same name of the class variable.
>>> class Student: default_age = 20 def __init__ (self, age): self.default_age = age
Suppose that you have the following code stored in a file called c:\ python\ studentfile.py. This code defines three different variables named default_age (at lines 2, 4, and 9).
1: class Student: 2: default_age = 20 3: def __init__(self, age): 4: self.default_age = age 5: 6: class Newstudent(Student): 7: "New student class" 8: def __init__(self, age=20): 9: self.default_age = age
# instance variable
The following code imports the previous module. Which variable is being used by the instance call at line 5?
1: 2: 3: 4: 5: 6:
import sys sys.path = sys.path + ['c:\ \ python'] import studentfile Joao = studentfile.Newstudent(15) Joao.default_age
Tip In order for Python to find your modules, the directory where you save them must be an entry of the sys.path list.
The answer is the instance variable of the newstudent class (line 9 from the first listing). In cases like this, the search order is defined as 1. instance variables 2. class variables 3. base classes variablesnote that the search order for base classes makes the deepest-level classes used first
The following variation is slightly different than the previous code. This example shows what you need to do to make the class Newstudent call the superclass's __init__ method.
Note that we are calling the __init__ method of the Student class (the superclass). The class constant Student.default_age is also used in this example. It is important to say that when calling unbound methods (methods that are not tied to an instance) like this one, you must explicitly say that the first argument is self.
Attributes of a Class Next, I list the attributes that classes expose to programmers. classname.__dict__ This attribute contains the class namespace dictionary.
>>> studentfile.newstudent.__dict__ { '__init__': <function __init__ at 799e90>, '__doc__': 'New student class', '__module__': 'studentfile'}
classname.__module__ This one provides the module name that contains the class.
The Python Class Browser The pyclbr module offers you the possibility of browsing all the information about classes that is stored in a specific module.
readmodule()
This function reads the module and returns a dictionary in the format { classname:classinfo}, where classinfo is an instance object of the class. basic syntax: variable = pyclbr.readmodule(module)
>>> import pyclbr >>> moduletobrowse = pyclbr.readmodule("profile") >>> for classname, classinfo in moduletobrowse.items(): print "Class name: %s" % classname Class name: HotProfile Class name: OldProfile Class name: Profile
>>> import pyclbr >>> moduletobrowse = pyclbr.readmodule("studentfile") >>> for classname, classinfo in moduletobrowse.items(): print "Class name: %s" % classname Class name: student Class name: newstudent
If you need to go deeper than that, you can look at the classinfo object. Python Instances Each instance defines its own namespace of data, and it inherits behavior from the class (and possible base classes) that have originated it. In order to create a new instance of a class, you just need to say
newinstance = classname()
class Person: def __init__(self, name): self.name = name self.family = [] def addmember(self, member): self.family.append(member)
For example, if you want to create a new instance of the chef class, you must type:
>>> anthony =
Person()
You can also pass arguments to the __init__ function of the class. These arguments can be used to set the initial values of an object. Let's see how it works.
To call the methods of a class, you have to use the dot notation:
>>> anthony.addmember("son")
You also need to use the dot notation to have access to variables (attributes) of each instance.
An interesting detail about Python object attributes is that they don't need to be declared inside the class before they get used because they can be created dynamically.
>>> class DummyClass: pass >>> colors = DummyClass() >>> color.alarm = "red"
The next example dynamically creates multiple attributes for the colors instance.
>>> class record: def __init__(self, **args): self.__dict__.update(args) >>> colors = record(alarm="red", normal="green") >>> colors.normal 'green'
The built-in functions isinstance() and issubclass() are always available without the need for importing any module because they are part of the __builtin__ module.
isinstance()
This function tests whether an object is an instance of a class. It returns 1 if the object is an instance. Otherwise, it returns 0. Note that this function handles subclass relationships as wellfor instance, isinstance(subclassinstance, superclass) returns true. basic syntax: isinstance(instance_object, class_object)
As you can see next, you can also use this function to identify the object's type. Note however, that this is behavior that works for noninstance objects. Floats and ints act quite differently from Python class instances (for instance, there is no way to
subclass types.IntType).
issubclass()
This function returns 1 if the class object classobj1 is a subclass (derived class) of the class object classobj2. basic syntax: issubclass(classobj1, classobj2)
Instance Attributes
obj.__dict__This is the dictionary that contains all the attributes defined for the obj instance.
obj.__class__It shows the class that has created the obj instance.
obj.__methods__This attribute is a list of all supported methods of the obj instance. Note that this attribute is available for lists and dictionaries, which are not class instances.
>>> a=[1,2] >>> a.__methods__ ['append', 'count', 'extend', 'index', 'insert', 'pop', 'remove','reverse', 'sort'] >>> b={ 1:''} >>> b.__methods__ ['clear', 'copy', 'get', 'has_key', 'items', 'keys', 'update', 'values']
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
def keyword definitions classes functions isinstance() issubclass() instances 2nd 3rd 4th 5th 6th accessing variables classes creating isinstance() function issubclass() function keywords class 2nd def methods classes calling modules pyclbr browsing classes obj.__class__ attribute obj.__dict__ attribute obj.__methods__ attribute object-oriented programming (OOP) Python classes and instances 2nd 3rd 4th 5th 6th programming object-oriented (OOP) Python classes and instances 2nd 3rd 4th 5th 6th pyclbr module browsing classes self argument statements class syntax functions isinstance() issubclass() readmodule() variables accessing instances classes 2nd
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 5. Object-Oriented Programming > Methods Handling
CONTINUE >
Methods Handling
Whenever you have to write methods in your classes, always keep in mind that the namespace searching order for attributes and methods is instance, class, and base classes; and don't forget that self is always the first or only argument to be used in method headers. Accessing Unbounded Methods The next example shows what you should do in order to unbind a class method and use it outside the class definition.
Line 1: Creates a class instance object. Line 2: Creates an object that references the class method. The method is still unattached to the object at this stage. Line 3: Executes the class method by transporting the instance reference (obj) and the list of arguments (args). Note that the first argument to an unbound method must be an instance of the correct class, or an exception will be thrown. Handling Global Class Variables The next example defines a function that prints a class variable. Every time a new instance is created, Globalcount increases.
print Globalcount.n class Couting: n = 0 def __init__(self): Globalcount.n = Globalcount.n + 1 inc = Couting() inc = Couting() printGlobalcount()
The next code overwrites the class variable x when subclassing the baseclass class.
class baseclass: x = 5 def multiply(self, a): return a * (self.__class__.x) class inherited(baseclass): x = 9 x = inherited() x.multiply(2)
After a method is defined, it uses the variable values that are associated to the current namespace.
>>> class A: n = 1 def printn(self): print self.n >>> class B(A): n = 2 >>> class C(B): n = 3
Calling Methods from Other Methods The next code exposes how simple it is to create a method to call another method.
>>> class c: def funcx(self): self.funcy() def funcy(self): print "Ni!" >>> obj = c() >>> obj.funcx() Ni!
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 5. Object-Oriented Programming > Special Methods
CONTINUE >
Special Methods
Python exposes some special methods that are easily highlighted in the code because they start and end with __ (double underscores). These methods override (inherit) built-in functions of the same name that are provided by Python itself. The next list shows some of the most used special methods. __init__(self) This is the constructor method, which is called during creation of instances. Usually, this is the place where the instance variables are initialized, among other things. __str__(self) This method is called when str() is called on instances of this type. It specifies how the object must be displayed when it is used as a string (for example, when a print command is applied to an object). __repr__(self) This method is called when repr() is called on instances of this type. This method provides a readable representation of the object. Usually, it is possible to re-create an object by using this method. Although not guaranteed, and the standard repr of an instance can't be executed to re-create the instance. __getattr__(self, name) Implement this method to trap or modify the access to nonexisting members, for example, returning the attribute self.name. __setattr__(self, name, value) This method allows you to control setting of attributes in the instance. It assigns the given value to the self.name instance's attribute. Note that you can also use "self.__dict__['attr'] = " to set attributes from within __setattr__ (if you do it the normal way, you will get infinite recursion). __delattr__(self,name) Implement this method to delete a specific attribute of an object. It's like saying del self.name. __del__(self) The __del__ method covers the deletion of the object. Be careful because sometimes it isn't immediately used when an object is destroyed (JPython behavior). CPython's garbage collector destructs objects as soon as their reference count
reaches zero. __cmp__(self,other) Implement this method to compare and return a negative, zero, or positive number. __hash__(self) Implement this method to generate a 32-bit hash index. __nonzero__(self) Implement this method to return 0 or 1 for truth-value testing. __call__(self) Classes that implement the __call__ method are callable, and their instances can be invoked like a function. This is the concept used by the built-in functions. The syntax obj(*args) is equivalent to obj.__call__(*args). __getitem__(self, index) This method supports list indexing, returning self[index].
>>> class Seq: def __getitem__(self, i): if i < 5: return i else: raise IndexError >>> s = Seq() >>> for i in s: >>> print i, 0, 1, 2, 3, 4 >>> print s[2] 2 >>> print s[6] Traceback (innermost last): File "<stdin>", line 1, in ? File "<stdin>", line 6, in __getitem__ IndexError
Next, you have some more special methods that deal with sequence and number-related methods. __len__(self)This method is called to return the length of the instance when
len() is called on an instance of this type. __add__ (self, other) Implement this method to return self + other. __sub__ (self, other) Implement this method to return self other. __mul__ (self, other) Implement this method to return self * other. __div__ (self, other) Implement this method to return self / other. __mod__ (self, other) Implement this method to return self % other. __neg__ (self) Implement this method to return self negated. __pos__ (self) Implement this method to return self positive. __abs__ (self) This method is called to return the absolute value of self when abs() is called on instances of this type. __inv__ (self) Implement this method to return the inverse of self. __lshift__ (self, other) Implement this method to return self shifted left by other. __rshift__ (self, other) Implement this method to return self shifted right by other. __and__ (self, other) Implement this method to return the bitwise and value of self and other. __or__ (self, other) Implement this method to return the bitwise or value of self and other. __xor__ (self, other) Implement this method to return the bitwise exclusive or value of self and other. __not__ (self) Implement this method to return the outcome of not self. (Note that there is no __not__() discipline for object instances; only the interpreter core defines this operation.)
__setitem__ (a, b, c) Implement this method to set the value of a at index b to c. __delitem__ (a, b) Implement this method to remove the value of a at index b. __getslice__ (a, b, c) Implement this method to return the slice of a from index b to index c1. __setslice__ (a, b, c, v) Implement this method to set the slice of a from index b to index c1 to the sequence v. __delslice__ (a, b, c) Implement this method to delete the slice of a from index b to index c1. The next example has a class definition that overrides some methods. Note that every instance of this class is callable.
>>> class Author: def __init__(self, argname): self.name = argname def __str__(self): return self.name def __repr__(self): return `self.name` def __call__(self, other): return self.name + other >>> obj = Author("Andre") >>> print obj Andre >>> obj 'Andre' >>> obj(" Lessa") 'Andre Lessa'
Python 2.0 has added a special set of operators to the language, which are called augmented assignment operators. These operators can be overriden by inserting an 'i'in front of the name, for example,
__isub__ implements in-place __sub__ (in other words, the -= operator). Also in this new release, you have access to the built-in method __contains__, which gives you access to customize the in operator. Method Attributes A method implements some special attributes that can be accessed from within the class that implements it. Suppose that you have a method called method: method.__doc__ Returns the documentation string of method. method.__name__ Returns the method name. method.im_class Returns the class that has defined method. method.im_self Returns the instance associated with method. The next example retrieves and prints the __init__ method's documentation string.
Overloading Operators Python operators are implemented for a class by implementing the equivalent special methods. This feature is called operator overloading. Extensive support exists for operators overloading via the double-underscored special methods such as __add__ and __init__.
The following example overrides the __add__ method and returns a tuple of results.
>>> class c: def __init__(self, x, y): self.x = x self.y = y def __add__(self, other): return (self.x + other.x, self.y + other.y) >>> obj1 = c(5,2) >>> obj2 = c(10,4) >>> print obj1 + obj2 (15, 6)
Of course, in real life, you would be more likely to want to return an instance of the class c, rather than just a tuple. Some others built-in methods you can use or overwrite are as follows:
class C: def __init__(self, value): self.value = value def __sub__(self, other): return self.value - other.value vara = C(5) varb = C(3) varc = vara - varb print varc
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
__del__(self) __delattr__(self, name) __getattr__(self, name) __getitem__(self, index) 2nd __hash__(self) __init__(self) __len__(self) __nonzero__(self) __repr__(self) __setattr__(self, name, value) __str__(self) handling 2nd 3rd 4th 5th 6th special 2nd 3rd object-oriented programming (OOP) handling methods 2nd 3rd 4th 5th 6th operators augmented assignment overriding overloading overloading operators overriding augmented assignment operators programming object-oriented (OOP) handling methods 2nd 3rd 4th 5th 6th special method 2nd 3rd
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 5. Object-Oriented Programming > Inheritance
CONTINUE >
Inheritance
A subclass is a class that inherits attribute names and methods from another classthe operation is called subclassing. A base class (superclass) is defined as a class that another class inherits attributes from. Base classes are listed in parentheses in a subclass header. You have to separate base classes by putting commas between them, within the parentheses. When you create a subclass, you can add or overwrite any methods of its base classes. Python classes can be created:
q
From scratch
For a conceptual standpoint, take a look at the following example Where, Base class = writing tools subclass = pen subclass = chalk Both subclasses pen and chalk inherit characteristics of the base class writing tools. The subsequent class defines a complex class called Employee.
class Employee: def __init__(self,name,salary=0): self.name = name self.salary = salary self.family = [] def raisesalary(self, percent): self.salary = self.salary + (self.salary * percent) def work (self): print self.name, "writes computer code." def hasfamily(self): return len(self.family) == 0 # returns a boolean result def addmember(self, x): self.family.append(x) def removemember(self, x): if len(self.family) > 0: x = self.family[-1] del self.family[-1] return x
def __init__ (self, name): Employee.__init__ (self, name, 50000) def work (self): print self.name, "works like any other employee."
Inherited methods of base classes aren't automatically called. It is necessary to call them explicitly. That's why, in the previous example, the Person.__init__ method had to call the Employee.__init__ method. It is always necessary to pass the self argument because base classes don't know what instance is being used. The previous example passes three parameters to the base class's __init__ method (the self reference, an argument, and a default value for the other argument). Multiple inheritance is defined by entering multiple classes in the header of a new class. The order used for informing the base classes really does matter. The precedence order, for a search in the base classes, starts at the classes located at the left side.
class A: pass class B(A): pass class C: pass class D(B,C): pass
The precedence order for class D inheritance is: B, A, C. Tip You always have to use fully qualified names when calling a superclass's method (if it has been overridden) because if the class has multiple base classes containing the same symbol, the first one found is used.
self.name = name def printname(self): print 'The name %s belongs to class A!'% self.name >>> class B(A): __baseclass=A def __init__(self, name): self.__ baseclass.__init__(self,name) def printname(self): print 'The name %s belongs to class B!'% self.name self.__ baseclass.printname(self) >>> class C(B): __baseclass=B def __init__(self, name): self.__ baseclass.__init__(self,name) def printname(self): print 'The name %s belongs to class C!'% self.name self.__ baseclass.printname(self) >>> A("monkey").printname() The name monkey belongs to class A! >>> B("parrot").printname() The name parrot belongs to class B! The name parrot belongs to class A! >>> C("ant").printname() The name ant belongs to class C! The name ant belongs to class B! The name ant belongs to class A!
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 5. Object-Oriented Programming > Polymorphism
CONTINUE >
Polymorphism
The concept of polymorphism doesn't really apply to Python objects because Python doesn't offer type declaration. This concept (having a function or method work for multiple argument types) is something you get for free with Python because of the dynamic typing. It does exist, but you don't usually explicitly code for it. When handling an obj.method expression, the meaning of method depends on the type, or class, of the object obj. Python doesn't know what type of object implements an interface until the program is running. This feature is called runtime binding. Python variables are typed, just not explicitly so. They are typed implicitly as the program uses them. For instance, if a program invokes abs(x), it doesn't make sense for x to be any object but a number. Therefore, the variable x is informally typed. The capability of dealing with objects at different levels of abstraction is one of the most important features of object-oriented programming and a very important part of Python. The next example shows how you can use just one function to implement poly morphism in Python. C++ refers to this variety of polymorphism as method overloading.
>>> class polymorph: def handle_int(self, argint): print '%d is an int'% argint def handle_str(self, argStr): print '%s is a string'% argStr def handle(self, arg): if type(arg) == type(1): self.handle_int(arg) elif type(arg) == type(''): self.handle_str(arg) else: print "%s is not a string nor an integer" % arg >>> p = polymorph()
The following code implements a class that does not work because the program tries to apply the general concept of polymorphism. This is a very common mistake that always catches programmers who don't know this concept doesn't exist in Python. Note that we try to define two different implementations of the same method (see lines 3 and 6). Right below this sample of code, you can see a traceback message that is provided by the interpreter when we try to run it.
1:>>> ## Beginning of a Python class THAT DOES NOT WORK 2: 3:>>> class Polimorpherror: 4: def __init__(self): 5: print 'No arguments!' 6: def __init__(self, args): 7: print 'One argument!' 8: self.args = args 9: 10:>>> ## End of a python class THAT DOES NOT WORK 11: 12:>>> x = Polimorpherror() >>> x = Polimorpherror() Traceback (innermost last): File "<stdin>", line 1, in ? TypeError: not enough arguments; expected 2, got 1
You cannot do method overloading as shown in the previous example. The next example presents a suggestion for the correct way to implement a solution for this problem.
>>> class Polimorpherror: def __init__(self, args=None): if args == None: print 'No arguments!'
The behavior of overloaded functions and methods is better implemented in Python using default arguments or by explicitly looking at the types of the arguments passed into the function. If you have a class for which you need to specify both a default constructor and a constructor that takes initial values of state as arguments, I suggest that you do so by transporting default arguments to the __init__ method.
>>> class Animal: def __init__(self, name = "Parrot"): self.name = name def printAnimal(self): print self.name >>> p = Animal() >>> p.printAnimal() Parrot >>> p = Animal("Monkey") >>> p.printAnimal() Monkey
If you want to initialize a variable but you don't want to enforce an object type, you can use the None type.
>>> class Animal: def __init__(self, name = None): self.name = name def printAnimal(self): print self.name
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 5. Object-Oriented Programming > Encapsulation
CONTINUE >
Encapsulation
All Python attributes (variables and methods) are public. Even though you cannot have private attributes in Python, you can use the following two agreements:
q
By convention, attributes preceded with a single underscore (for example, _n) are to be viewed as internal variables, not to be used externally. Attributes starting with double underscores (for example, __n) aren't explicitly exported. They are renamed to _Class__Variablename when byte compiled. Because the name of a class is used as part of the variable name, the attribute __n (when inside a subclass) isn't the same __n variable defined at a base class. This is probably the closest to private that you will get. But, it isn't really a private implementation because when you know the name of the class, you can access the attribute. C++ programmers probably know this as name mangling.
We cannot say that Python supports private attributes because it is still possible to have access to the attributes if you know the class and attributes names. For example, in a class called C, the attribute self.__attr becomes self._C__attr, when exported from the class. Hence, you can access this attribute by referencing it as _C__attr.
>>> class Number: def __init__(self, value): self._n = value self.__n = value def __repr__(self): return '%s(%s)'% (self.__class__.__name__, self._n) def add(self, value): self._n = self._n + value def incr(self): self._n = self._n + 1
Based on the previous class, we will have some interactive examples next.
>>> a = Number(20) >>> a Number(20) >>> a.add(4) >>> a Number(24) >>> a.incr() >>> a Number(25) >>> a._n 25 >>> a._n = 30 >>> a Number(30) >>> a._Number__n 20
The important thing to remember is that nothing in Python is private (unless it is hidden within a C extension type). To demonstrate that you can use default arguments to help storing the environment variables in a variable from the class namespace, the next example initializes the value of the variable n by using a default argument. The value of n is assigned at the time of defining the function and is stored at the class namespace.
>>> v = 10 >>> class C: def storen(self, n=v): return n >>> objA = C() >>> objA.storen() 10 >>> v = 20 >>> objB = C() >>> objB.storen() 10 >>> n = 30 >>> objC = C()
>>> objC.storen() 10
Note that the value of n remains constant for all instances of the class C. The following example shows that it is possible to manipulate the internal attributes of an object by directly accessing the members of a class.
>>> class fun: def __init__(self): self.total = None >>> a = fun() >>> b = fun() >>> a.total = 2 >>> b.total = 3 >>> print a, b 2 3
In this next example, we hide the a() method definition by preceding it with two underscores. Note that if you later need to access this method (and you don't want to rename it), you must create a reference to the method, as shown in the following example.
>>> class C: def __a(self): print "ni!" b = __a >>> a = C() >>> a.b() ni!
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 5. Object-Oriented Programming > Metaclasses
CONTINUE >
Metaclasses
A metaclass is just a class that is used as a template to create class-like entities. Normally, you create instances based on classes. The goal here is to create classes (metainstances) based on other classes (metaclasses). The resulting metainstances are used as base classes for your own classes. The whole idea is to offer you the possibility of operating Python's internal class-handling engine. Everything that usually happens behind the scenes while manipulating your classes and objects now can be accessed and changed. The meta instance makes it easier for you to handle the task of modifying the attribute lookup behavior of objects. Prior to Python, version 1.5, it was necessary to use C extensions in order to define metaclasses. The subsequent code defines a simple metaclass and its supporting classes. Note that this structure doesn't cover the whole model.
>>> import types >>> class METACLASS: def __init__(self, name, bases, namespace): self.__name__ = name self.__bases__ = bases self.__namespace__ = namespace def __call__(self): return METAINSTANCE(self) >>> class METAINSTANCE: def __init__(self, metaclass): self.__metaclass__ = metaclass def __getattr__(self, name): try: value = self.__metaclass__.__namespace__[name] except KeyError: raise AttributeError, name if type(value) is not types.FunctionType:
19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29:
return value return METHODWRAPPER(value, self) >>> class METHODWRAPPER: def __init__(self, function, metainstance): self.function = function self.instance = metainstance self.__name__ = self.function.__name__ def __call__(self, *args): return apply(self.function, (self.instance,) + args)
Line 2 : Defines the metaclass METACLASS. Lines 3-6 : Creates a new metaclass. The __init__ method expects three arguments: The metainstance name, a tuple of base classes, and a dictionary of the metainstance namespace. Lines 7-8 : Invokes METAINSTANCE.__init__ when METACLASS is called, returning a metainstance. Line 10 : Defines the metainstance METAINSTANCE. Line 13 : Handles the access to attributes of the user instance by checking whether it is part of the user class namespace (lines 14-17). If the attribute is a value, it returns the value. Otherwise, if the attribute is a function, it returns an instance of the METHODWRAPPER class, which is actually the result of the function call. Line 22 : Defines the METHODWRAPPER class, which handles all the accesses to the method attributes of the user class. Now that we are ready to call metaclasses, you can use metainstances as base classes of your own classes, trapping the access to your class objects. The next line of code creates an instance of a metainstance.
We are creating a class called BASECLASS whose behavior is inherited from the METACLASS constructor class. The METACLASS.__init__ method is invoked at this stage. From now on, every class that you createwhich uses BASECLASS as the base classwill inherit the whole behavior that you have specified in the METACLASS definition. The following code exemplifies a user class that has our BASECLASS as the base class.
>>> class CEO(BASECLASS): def push(self, name): self.name = [name] def pop(self): if len(self.name) > 0: item = self.name[-1] del self.name[-1] print item
>>> ITCEO = CEO() >>> ITCEO.push("Andre") >>> ITCEO.pop() ['Andre'] >>> ITCEO.name []
Note that ITCEO = CEO() invokes METACLASS.__call__, which creates a METAINSTANCE instance, whereas all the other calls invoke METAINSTANCE.__getattr__. More details about metaclasses can be found at the following addresses: http://www.python.org/doc/essays/metaclasses/ and MessThe Meta-Extension System Set (old stuff) at http://starship.python.net/crew/da/mess/doc/Tutorial.
Mess is a set of extensions that allows the creation of new types, among other things. It's not certain whether it will ever be integrated into Python, but its documentation can provide a lot of help in understanding metaclass concepts. Maybe you will like to take a look at the ExtensionClass extension by Digital Creations that uses metaclasses to allow creation of class-like objects in C (and is a lot easier to use than Mess). This extension illustrates how the Python class mechanism can be extended, and provides a lightweight mechanism developed for making Python extension types more class-like. Classes can be developed in an extension language, such as C or C++, and treated like other Python classes. http://www.digicool.com/releases/ExtensionClass/
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 5. Object-Oriented Programming > Summary
CONTINUE >
Summary
Python is a language that implements object-oriented programming (OOP) by supporting classes and class instances. A class is a template from which objects can be created. It has its own namespace and stores object attributes and methods, which can be inherited from other base classesa process called subclassing. A class can also contain class variable assignments. These variables are shared by all the class instances, and they are part of the class namespace. All class attributes (variables and methods) are public. In order to identify the right variable that is used when you get multiple variables with the same name within your code, the following search order is followed: instance variables, class variables, and base class variables. Python has a module called pyclbr (Python Class Browser) that offers you the possibility of browsing all the information about classes that is stored in some other specific module. Note that most of this information can also be deduced through introspection. pyclbr gives you another benefit in that you don't need to import the module. Each object created from a class is an instance of a class, which has some specific properties: identity, object type, attributes, methods, and value. Classes and instances have built-in attributes that provide access to their internal definitions (namespace, name, and so on). The built-in functions isinstance() and issubclass() are provided to help determine the inheritance properties of instance and class objects. Each instance defines its own namespace of data, and it inherits behavior from the class (and possible base classes) that have originated it. Python object attributes don't need to be declared inside the class before they get used because they can be created dynamically.
Class methods can be unbound and used outside a class definition. They also carry some special attributes that can be called from within the class that implements them. These attributes enable the access to the method's name, the method's documentation string, and so on. All method definitions must carry the argument self, whose function is to transport a reference of the object in a way so that when a method is called, it knows which object should be affected. Python exposes some special methods, such as __init__(), __str__(), and so on. These methods inherit built-in functions of the same name that are provided by Python itself. Python operators can be re-created by remapping their built-in functions and methods. This feature is called operator overloading. Extensive support exists for operators overloading via the doubleunderscored special methods such as __add__() and __div__(). Python classes can be created from scratch by using single inheritance and multiple inheritance. A subclass is a class that inherits attribute names from another class, whereas a base class is defined as a class that another class inherits attributes from. When you create a subclass, you can add or overwrite any method from its base classes. However, inherited methods of base classes aren't automatically called. It is necessary to call them explicitly. The order used to inform the base classes in a class header is really important. The precedence order for attribute searches in the base classes starts at the class located at the left side. Python doesn't offer type declaration because it doesn't know what type of object implements an interface until the program is running. This feature is called runtime binding. A single underscore preceding the attribute name is used to point out internal attributes that shouldn't be used externally. Attributes starting with double underscores aren't explicitly exported. Python also offers you the possibility of operating its internal class handling engine by using metaclasses and metainstances. A metaclass is just a class used as a template to create class-like entities, and the use of metainstance makes it easier for you to handle the task of modifying the attribute lookup behavior of objects.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark 2002, O'Reilly & Associates, Inc. CONTINUE >
Web Development > Python Developer's Handbook > 5. Object-Oriented Programming > Code Examples
CONTINUE >
Code Examples
This application subclasses an exception class and executes the commands stored in a file. The filename is asked by the application.
Listing 5.1 Configuration File (File configfile.py)
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35:
### # Program: Configuration File # Author: Andre S Lessa ### ### import modules import exceptions, sys configfile = raw_input("Configuration File: ") class ConfigError (exceptions.Exception): def __init__(self, arg=None): self.args = arg try: try: file = open(configfile) lines = file.readlines() finally: file.close() except: print "Error. Invalid file name." sys.exit() lines[0] = lines[0][:-1] if lines[0] != "CFG2000": raise ConfigError, "Invalid header." lines = lines[1:] for line in lines: try: exec line
except LookupError, b: if b.args[0] == "list index out of range": print "Error. Invalid index entry" else: print "Error. Generic LookupError entry" except SystemExit: print "Error. sys.exit() cannot be used."
Lines 12-14: The class ConfigError is created. It inherits all the attributes from the exceptions.Exception class. Line 29: Raises our new exception class. In order to test this program, we have to create a file called config.txt that contains the following lines:
CFG2000 print print "Configuration File" print "------------------" server = "SRV001" port = 80 print "Server: ", server print "Port: ", port
The next interaction shows how to call the program. It also shows the results provided by the program when no exception is raised.
C:\ Python>python configfile.py Configuration File: config.txt Configuration File -----------------Server: SRV001 Port: 80 C:\ Program Files\ Python>
This simple program creates a class structure that stores and prints a list of groceries.
Listing 5.2 Groceries List (File groceries.py)
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34:
# Author: ###
Andre S Lessa
class grocery: "Items that you need to buy at the grocery store." def __init__(self, name, quantity=1): self.name = name self.quantity = quantity items = { } print "Type ENTER when you are done." while 1: name = raw_input("Grocery name: ") if name == "": break quantity = raw_input("%s quantity: " % (name)) if quantity == "": items[name] = grocery(name) else: items[name] = grocery(name,quantity) print "------------------------\ nList of groceries to buy" print "------------------------" for item in items.keys(): print "Grocery : ", items[item].name, print "\ tQuantity: ", items[item].quantity print "---------"
Line 9: Declares the grocery class. Line 10: The class's documentation text. Line 11: A default value is defined for the quantity argument. Lines 22-25: Uses a different interface to initialize the object, depending on the information provided. Lines 31-32: Provides access to the object attributes. The next interaction shows how the program works.
Grocery name: bananas bananas quantity: 12 Grocery name: apples apples quantity: 6 Grocery name: pears pears quantity: 8 Grocery name: pineapple pineapple quantity: Grocery name: -----------------------List of groceries to buy -----------------------Grocery : pineapple Quantity: Grocery : pears Quantity: Grocery : apples Quantity: Grocery : bananas Quantity: --------C:\ Python>
1 8 6 12
This file introduces two classes and one function that extensively manipulate class methods and attributes.
Listing 5.3 Company employees (File company.py)
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
### # Program: Company employees # Author: Andre S Lessa ### ### import modules import types class Employee: "Generic class for all company employees" __employees = 0 def __init__(self,name,salary=500.00): self.name = name self.salary = salary self.family = [] Employee.__employees = Employee.__employees + 1 def __str__(self): return "employee: %s" % self.name
24: def raisesalary(self, percent): 25: self.salary = self.salary + (self.salary * (1.0/percent)) 26: 27: def job(self): 28: print self.name, "writes Python code." 29: 30: def hasfamily(self): 31: return len(self.family) > 0 32: 33: def addmember(self, name): 34: self.family.append(name) 35: 36: def removemember(self, arg): 37: if len(self.family) > 0: 38: if type(arg) == type(1): 39: self.removemember_int(arg) 40: elif isinstance(arg, types.StringType): 41: self.removemember_str(arg) 42: 43: def removemember_int(self, index): 44: member = self.family[index] 45: del self.family[index] 46: return member 47: 48: def removemember_str(self, name): 49: for member in self.family: 50: if member == name: 51: del self.family[self.family.index(member)] 52: return member 53: 54: def __getitem__(self, index): 55: member = self.family[index] 56: return member 57: 58: class Leader(Employee): 59: "Company's Leader of the employees" 60: def __init__ (self, name): 61: Employee.__init__ (self, name, 1500.00) 62: def job(self): 63: print self.name, "supervises who writes Python code." 64: 65: def totalemployee(): 66: return Employee._employee_employees Line 10: Defines the Employee class. Line 13: Class variable __employees.
Line 19: Increments the number of employees. Line 31: Returns a logical value (0 or 1). Lines 36-41: Implements polymorphism by enabling the user to enter both string and integer values. Lines 43-52: Helper methods for the polymorphism implementation. Line 54: Enables the slicing of employees instances. Line 58: Defines a subclass Leader that inherits attributes from the Employee class. Lines 60-63: The __init__() and the job() methods are overwritten. Line 65: Provides a function that returns the total number of employees who are currently part of the class. The following interaction shows how the classes must be used.
>>> import company >>> andre = company.employee("Andre") # Creates an employee instance >>> print andre employee: Andre >>> print andre.salary 500 >>> andre.raisesalary(10) # Raises his salary in 10 percent >>> andre.salary 550.0 >>> andre.job() # Shows his job description Andre writes Python code. >>> andre.hasfamily() 0 >>> andre.addmember("Renata") # Add a member to his family >>> andre.addmember("Joao Pedro") # Add a member to his family >>> andre.addmember("Rebecca") # Add a member to his family >>> andre.hasfamily() # Returns 1 or 0 1 >>> andre.family ['Renata', 'Joao Pedro', 'Rebecca'] >>> andre.removemember("Joao Pedro") # Remove string member from list >>> andre.family ['Renata', 'Rebecca'] >>> andre.removemember("Renata >>> andre.family ['Rebecca'] >>> andre.removemember(0) # Remove index member from list >>> andre.family []
>>> andre.addmember("Joao Pedro") >>> andre.addmember("Renata") >>> andre.addmember("Rebecca") >>> andre[0] 'Joao Pedro' >>> andre[1 'Renata' >>> andre[2] 'Rebecca' >>> company.totalemployee()# Shows the total number of employees 1 >>> renata = company.employee("Renata") >>> company.totalemployee() 2 >>> Joao = company.Leader("Joao Pedro") # Creates a leader instance >>> Joao.salary 1500.0 >>> Joao.job() Joao Pedro makes food >>> company.totalemployee() 3 >>>
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > II: Advanced Programming
CONTINUE >
Web Development > Python Developer's Handbook > 6. Extending and Embedding Python
CONTINUE >
Web Development > Python Developer's Handbook > 6. Extending and Embedding Python > Extending and Embedding Python
CONTINUE >
necessary files needed for compiling extensions, so you don't need a full source distribution in this case. On Red Hat like systems, this package is called python-devel. The Python official documentation and the links that are listed throughout this chapter are a good source of information about this topic. Embedding and Extending the Python Interpreter: http://www.python.org/doc/current/ext/ext.html Some people using Win32 claim to have successfully used the Free Borland Compiler to compile Python extension modules. Free Borland Compiler: http://www.borland.com/bcppbuilder/freecompiler/ Some people also successfully used GNU gcc with the mingw32 runtime. There is some info at http://starship.python.net/crew/kernr/mingw32/Notes.html
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
embedding in non-Python applications programming languages C extending and embedding Python C++ extending and embedding Python programs non-Python embedding Python objects in software non-Python embedding Python objects in
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 6. Extending and Embedding Python > The Python/C API
CONTINUE >
Web Development > Python Developer's Handbook > 6. Extending and Embedding Python > Extending
CONTINUE >
Extending
Because Python cannot access C/C++ functions in a straightforward way, it is necessary to handle the conversion between Python and C/C++ data types when putting them to work together. That is when we use the Python extension modules. These extensions work like a thin wrapper of functions written in C/C++ that are necessary to bring the C/C++ functionality to the developer. It is widely known that interpreted languages execute intensive applications slower than compiled languages. As a result, it is a good choice to implement as extension modules the application routines that need to run fast, such as network access, database manipulation, and routines that intensively use the graphical interface. Keep in mind that you always have to think about whether it is really necessary to implement routines as extension modules. Are you sure that the processing speed will get better by calling C functions instead of just using plain Python? Before starting to implement anything in C, I suggest that you analyze and test your Python code. Check to see whether it can be optimized. Profile it, and only if you find some big problem, create C extensions. As an example, if you have the execution time of a function that only accounts for 1% of the program execution time, you have only reduced total execution time by 0.5%. And remember, before you implement some surreal extension, to first check the Python distribution and the contributed modules. What you need might already be there. Some good links to where you can check for existing modules are The Python contributed modules page at http://www.python.org/download/Contributed.html The Vaults of Parnassus collection of Python resources at http://www.vex.net/~x/parnassus/ The extension modules should be used to write specific operations, and not complete applications. By doing this, you will spend less time developing the wrapping interfaces.
The next two links provide a good source of information about writing an extension module: "How to Write a Python Extension," by Michael P. Reilly: http://starship.python.net/crew/arcege/extwriting/pyext.html "Extension Classes, Python Extension Types Become Classes," by Jim Fulton: http://www.digicool.com/releases/ExtensionClass/ Creating New Extensions I presume that if you came this far, you are sure that you want to use extension modules. So, let's start developing something. First, in many places, you will see the naming convention for extension module files defined as modulenamemodule. c. Second, all extension modules must include the Python/C API "<Python.h>" system header file. The next example is an extension module called helloworldmodule.c that is used to demonstrate how easy it is to create a Python extension.
/* File: helloworldmodule.c */ #include "<Python.h>" /* external function*/ static PyObject *sayhello(PyObject *self) { return Py_BuildValue("s","Hello Python World!"); } /* name binding table */ static PyMethodDef hellomethods[] = { {"say", sayhello, METH_VARARGS }, {NULL, NULL} /* sentinel */ }; /* initialization function*/ DL_EXPORT(void) inithello() { Py_InitModule("hello", hellomethods);
After linking this module to your interpreter, it becomes promptly accessible for your use (see Figure 6.1).
Figure 6.1. As you can see, there is no difference between the way you use an extension module and the other modules.
It is important to stick to the naming convention because when the module is first imported, the initmodulename() function is called. Every time you implement a C function that Python will call, you have to define two arguments. The first one is called self, and it is a pointer to the called object. The argument self is used when implementing built-in methods to point to the bound object. When a function is implemented, self is set to NULL. The other argument is usually called args, which is a pointer to a tuple object that contains the arguments of the function.
Check out another example. This one passes arguments between Python and C.
/* File: systemmodule.c*/ #include "<Python.h>" static PyObject *system_command(PyObject *self, PyObject *args) { int return_status; char *program; char *argument; static char statement[255]; if (!PyArg_ParseTuple(args, "ss", &program, &argument)) return NULL; sprintf(statement, "%s %s", program, argument); return_status = system(statement); return Py_BuildValue("i", return_status); } static PyMethodDef systemmethods[] = { {"command", system_command, METH_VARARGS}, {NULL, NULL} }; DL_EXPORT(void) initsystem() { Py_InitModule("system", systemmethods); }
The next set of instructions calls the command() function that is part of the system module, which is stored in the systemmodule.c file.
All interface items are Python objects. Thus, function arguments and return values are pointers to PyObject structures. PyObjects are C representations of real Python objects. All PyObjects have a reference count. You shouldn't declare a variable of type PyObject. Instead, you have to declare PyObject * pointers to the actual storage of the object. Because all Python objects have a similar behavior, they can be represented by a single C type (PyObject *). Note that a variable of type PyObject can be defined, but it won't be of much use. In order to implement basic extensions, you essentially use the following commands: PyArg_ParseTuple(args, format, arg1 [, arg2 [,]])Checks the argument types and converts them to C values. It returns a true value when the checking and the conversion doesn't return any errors. PyArg_ParseTupleUsed to parse the PyObject that contains the function arguments (args). The second argument is a format string that lists the object types that you expect to collect, and all the other arguments are pointers to be filled with values from the parsing operation. Note that you can add the function name to the format string to make error messages a bit more informative. Py_BuildValue(format, Cvar1 [, Cvar2 [,]])Converts C objects into Python Objects based on the formatting string. Py_BuildValue is mostly used when it is necessary to return values to the Python interpreter. Tip C functions that return a void argument must return the Python type called None.
For this other example, let's create a function that takes two Python objects and returns a pointer to a Python object.
/* File: divisionmodule.c*/ #include "<Python.h>" static PyObject *division_function(PyObject *self, PyObject *args) { PyObject *result = NULL; long a, b; if (PyArg_ParseTuple(args, "ii", &a, &b)) { result = Py_BuildValue("i", a / b); } return result; } static PyMethodDef divisionmethods[] = { {"divide", division_function, METH_VARARGS}, {NULL, NULL}, }; DL_EXPORT(void) initdivision() { Py_InitModule("division", divisionmethods); }
Importing an Extension Module As you could see in the previous example, in order to allow Python to import your module, a few steps are required. Step 1. Create a method array. Each element of this array is a structure that contains: the function's name to be exported to the Python interface, the C function's name and a indicator that shows how arguments must be passed. Each function of the module to be exported to Python must be an element in this array. Note that the last element of the array works as a sentinel, and it must contain NULLs.
The third argument of each array entry can beMETH_VARARGS means that the arguments are in a tuple format.METH_VARARGS | METH_KEYWORDS indicates that keyword arguments are also allowed. It will just pass a NULL for the extra argument if no keyword arguments are given. The modulenamemethods[] array has a fourth optional element, which is a documentation string. Step 2. Create the initialization function of the module. This function should be declared as non-static. All the others should be defined as static in order to avoid name conflicts with other modules. The initmodulename() function is automatically called by the interpreter. The DL_EXPORT() definition is used to expose the module entry point. Note that the DL_EXPORT macro only does something on the Win32 platform.
In this example, the Py_InitModule creates a "system" module object based on the array systemmethods. You can verify that by checking the sys.modules dictionary after importing the extension module. Formatting Strings Whenever you use the PyArg_ParseTuple() or the Py_BuildValue() function, you must follow a mechanism that is based on some formatting tables, which are mentioned next, in order to make the correct conversion between Python types and C types. Both functions check the arguments type by looking at a formatting string. All the elements of the formatting string must match in type and number with the variables that are also part of the function's list of arguments. Sometimes, it isn't strictly necessary to have both sides (C and Python) matching in type. The reality is that the receiving field only has to be big enough to fit the received value; hence, the Python type called
float is easily stored by a C double variable. Of course, using a C type that doesn't match the format character will cause problems that might only affect some platforms. The literals |, :, and ; have special meanings when placed inside a formatting string. | The remaining arguments in the formatting string are optional. The C variables will keep their original values in case they aren't assigned to any arguments. You should make sure that the variables are initialized for optional arguments. : The string after the colon is the function name to be called in case of error messages. ; The string after the semicolon is the user error message that must substitute for the original error message. Tip A given formatting string must contain only one |with : or ; because : and ; are mutually exclusive.
Table 6.1 covers all the elements that can be part of a PyArg_ParseTuple's formatting string. Just to remind you, PyArg_ParseTuple() is used to convert Python objects into C objects.
Table 6.1. A PyArg_ParseTuple's Formatting String Elements Element Python Type s string C Type char * Notes The C string is NULL terminated; The Python string cannot be None and it cannot contain embedded NULLs, otherwise, a TypeError exception is raised. s# z z# b h i string string or None string or None integer integer integer char *, int char * char *, int char short int int Pointer to the character string and its length. Note that s# allows embedded NULLs in the string. Python string can be None. If that happens, the C pointer is set to NULL. Similar to s#. Stores a tiny int (8-bit integer) in a char.
l c f d D O
integer
long int
string of length 1 char float float float complex object double Py_complex PyObject * The C variable (of type PyObject *) stores an s pointer to the address of the Python object. The object reference count isn't increased.
O!
object
typeobject, PyObject * Similar to O, but it also looks at the address of the Python-type object that specifies the required type. If the Python object doesn't match the required type, a TypeError exception is raised. function, variable Converts a Python object into a C variable of arbitrary type (void *), using a function. It is equivalent to: status = function(object, variable). The returned status should be 1 for success and 0 for failure.
O&
object
string
PyStringObject *
Note Using anything other than the given types could very easily cause problems on some architectures.
If the Python object is a tuple, the number of matching variables passed to the C function must be equal to the number of formatting elements informed. A tuple is indicated in the formatting string by placing the formatting elements between parenthesis. The Py_BuildValue function is used to return values to the Python program that has called the extension module. Its functionality is similar to PyArg_ParseTuple. This function doesn't create a tuple of one element automatically, unless you enclose the single formatting element in parentheses. Table 6.2 covers the Py_BuildValue function and all the elements that can be part of its formatting string. Just to remind you, this function is used to convert C objects into Python objects.
Element C type s char * s# z z# b h i l c f d O O! O& S N char *, int char * char *, int char short int int long int char float double PyObject * typeobject, PyObject * PyObject * PyObject *
Python type string string string or None string or None integer integer integer integer string of length 1 float float object object
Notes If the C string pointer is NULL, None is returned. Converts the C pointer to a character string and its length into a Python string object. If the C pointer is NULL, None is returned. Similar to s. Similar to s#.
It returns a Python object, or NULL if an error occurs. Same as O. Similar to O, except that the reference count isn't incremented.
The following list complements the previous table by showing how Python tuples, lists, and dictionaries are generated.
q
Matching items between parenthesis are converted into a Python tuple. Matching items between square brackets are converted into a Python list. Matching items between curly braces are converted into a Python dictionary. Each consecutive pair of values forms a dictionary entry in the format (key, value).
Exporting Constants In addition to methods, you can also export constants back to Python. You just need to bind the constant name to the module namespace dictionary.
static PyMethodDef pimethods[] = { {NULL, NULL} }; DL_EXPORT(void) initpi() { PyObject *module, *dictionary; PyObject *pivalue; module = Py_InitModule("pi", pimethods); dictionary = PyModule_GetDict(module); pivalue = PyFloat_FromDouble(3.1415926); PyDict_SetItemString(dictionary, "pi", pivalue); Py_DECREF(pivalue); }
Error Checking You must indicate errors in your extension module by returning NULL to the interpreter because functions signal errors by returning NULL. If your function has no return at all, you need to return the None object.
return Py_BuildValue("");
or
In case you need to raise an exception, you can do that prior to the return NULL statement. Note that returning NULL without raising an exception is bad.
Handling Exceptions
Exceptions work as functions in the Python/C API. For example, to raise an IndexError exception,
you just need to call PyExc_SetString() prior to the return NULL statement. Extension modules also support the creation of new exception types.
/* File: testexceptionmodule.c*/ #include "<Python.h>" static PyObject *exception = NULL; static PyMethodDef testexceptionmethods[] = { {NULL, NULL} }; DL_EXPORT(void) inittestexception() { PyObject *module, *dictionary; module = Py_InitModule("testexception", testexceptionmethods); dictionary = PyModule_GetDict(module); exception = PyErr_NewException("testexception.error", NULL, NULL); PyDict_SetItemString(dictionary, "error", exception); }
Check Appendix A for more information about the Python/C API exception functions, including how to handle threads in your extensions. Reference Counting We all know that programmers are responsible for dynamic memory allocation and deallocation in C and C++. However, Python extensions don't benefit from all the security provided by the Python runtime system. There are a lot of things that you have to be worried about. The main thing is reference counting.
The core Python counts references to every Python object that is created, which enables it to deallocate an object when it doesn't have any more references. If an object's reference count reaches 0, this object is marked for deallocation. If this same object references other objects, their references are decremented too. The code for deallocating referenced objects occurs in the object destructor. The counter is incremented when a reference to the object is created, and it is decremented when the reference is deleted. If the reference count becomes zero, the object is released. That's how Python works. However, Python extensions don't have this functionality built in. You have to increment (Py_INCREF) and decrement (Py_DECREF) the references by yourself. You can be sure that your reference counting is wrong if your system crashes when you either return a value from the extension module or when you exit the application. Too few Py_INCREFs can cause the application to freeze at an unspecific time, whereas too few Py_DECREFs cause memory leaks that drive the application to use more and more memory for the process. An object reference count is defined as the number of owned references to it. The owner of a reference is responsible for calling Py_DECREF(). It is also possible to borrow a reference to an object. The borrower should neither call Py_DECREF() nor use the reference after the reference owner has disposed of it. If you are borrowing a reference, make sure that you are absolutely certain the owner will not release the reference while you are using it. To make a borrowed reference to become an owned reference, you just need to call Py_INCREF() for the mentioned object. Take a look at following lines of code:
You don't need to call Py_DECREF() before leaving the module that implements this kind of code because PyArg_ParseTuple() returns borrowed references, and releasing references that you don't own can cause you severe problems. Py_INCREF and Py_DECREF are implemented as macros, so only pass a variable as the argument because the argument is evaluated twice after macro expansion.
Python Official DocumentationReference Counts http://www.python.org/doc/current/api/refcounts.html "Debugging Reference Count Problems," by Guido van Rossum http://www.python.org/doc/essays/refcnt.html Building Extensions in C++ Python has a C-based interpreter, and it becomes a bit harder to adjust code to compile it as C++ because Python has some restrictions when it comes to creating extension modules using C++. However, there are some things that you can do in order to reduce your problems. The next hints will help you to link Python to a C++ compiler. The problems depend on the C++ compiler that you are using. However the most common ones are discussed in the following paragraphs. If the Python interpreter is compiled and liked by a C compiler, you cannot use global or static C++ objects with constructors. Unless you use a C++ compiler. But, you can initialize the globals in the module's init function instead. You need to place extern "C" { }around the Python include files. You need to define the Python API as a C segment to the C++ compiler as well.
If the header files for Python on your machine already include the extern "C" { }stuff, adding an extra extern "C" block will cause an error on most compilers (as the extern "C" syntax is not valid C). Functions that are going to be called by the interpreter (in particular, module initialization functions) have to be declared using extern "C".
You have these same concerns when building a dynamic module. In fact, there are more concerns (for instance, the DL_EXPORT stuff isn't required if the module is statically linked to the interpreter). You can use Python to access many C++ class libraries. You just need to have the right wrapper that provides the necessary access to the libraries. Tip When embedding Python in your C++ code, it isn't necessary to recompile Python itself using C++. However, if you want to use C++ extension modules, the Python interpreter might have to be compiled with a C++ compiler though recent Linux distributions should work fine without a recompile. For more information, check out "Binding Python to C++," by Guido van Rossum http://www.python.org/workshops/1994-11/C++Python.txt
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
deallocating objects declaring variables PyObject decrementing counters 2nd 3rd double variable elements b 2nd c 2nd d D d f 2nd h 2nd i 2nd l 2nd N O 2nd O! 2nd O& 2nd s S s S s# 2nd z 2nd z# 2nd embedding Python objects 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th error checking extension modules 2nd exceptions handling extension modules 2nd raising returning NULL values extension modules creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th importing extensions building, C++ 2nd creating implementing extern C
{ } block { }block f element 2nd float variable formatting strings 2nd 3rd 4th 5th functions command() Py_BuildValue() string elements Py_DECREF() 2nd Py_INCREF() 2nd PyArg_ParseTuple() string elements 2nd h element 2nd handling exceptions extension modules 2nd i element 2nd implementing extensions importing extension modules incrementing counters 2nd 3rd l element 2nd modules extension creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th importing N element NULL value checking errors, extension modules returning without raising exceptions O element 2nd O! element 2nd O& element 2nd objects deallocating embedding in non-Python applications 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th owned references programming languages C extending and embedding Python 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th C++ building extensions 2nd
extending and embedding Python 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th programs non-Python embedding Python objects in 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th Py_BuildValue() function string elements Py_BuildValue(format, Cvar1 [, Cvar2 [, ]]) command Py_DECREF() function 2nd Py_INCREF() function 2nd PyArg_ParseTuple command PyArg_ParseTuple() function string elements 2nd PyArg_ParseTuple(args, format, arg1 [, arg2 [, ]]) command PyObject declaring variables Python recompiling raising exceptions returning NULL values recompiling Python reference counting extension extension modules references borrowed owned returning NULL value without raising exceptions s element S element s element S element s# element 2nd self argument software non-Python embedding Python objects in 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th strings formatting 2nd 3rd 4th 5th values NULL checking errors, extension modules returning without raising exceptions variables declaring
PyObject double float verifying errors extension modules 2nd z element 2nd z# element 2nd
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 6. Extending and Embedding Python > Compiling and Linking Extension Modules
CONTINUE >
On UNIX, Python modules written in C are easily identified by looking at the /usr/lib/Python1.5 directory. Most of the time, they are the shared library files with the .so extension. Although, if you are using HPUX, the extension is .sl, and on some others it is just .o. The next few steps show how to create static extensions on UNIX. Step 1. You need to copy your module to the Modules directory. Step 2. You have to add the following entry to the end of the /modules/Setup.in configuration file, which is located in the Python source tree. This file has the list of all the external libraries needed by the interpreter.
For example,
hello /mnt/hda/python/helloworldmodule.c
If your extension module requires additional libraries, add the argument -llibraryname at the end of the line. For example,
The *static* flag builds the modules as static modules. The other option is to use the *shared* flag, which means that they have to be built as shared modules (known as DLLs on Windows). The last step is to recompile Python as normal to include the extra module by typing ./configure and make in the top of the Python Source tree. The Python interpreter is rebuilt after that. To execute the new interpreter and test your new extension module, just call it like this:
./python
The following instructions are based on the use of Microsoft Visual C++ version 5. First, you need to inform Python's include path. To do that, go to Tools, Options, Directories (see Figure 6.2).
Figure 6.2. You need to inform the include path.
It is also necessary to inform the library's location (see Figure 6.3). You need to add the python15.lib directory to your Tools, Options, Directories, Library files.
Figure 6.3. You need to inform the python15.lib path.
Now, the rest is easy. 1. Using a text editor, open the \PC\config.c file. 2. Look for the first comment. You need to add an external reference to the init function of your module.
3. Locate the next comment. You need to add the module name and the init function.
4. Using a text editor, open the /PCbuild/python15.dsp file. 5. Go to the end of the file. Locate the entry that references the yuvconvert.c source file. You need to add the location of your module's source file just before that entry.
SOURCE=..\Modules\yourmodulenamemodule.c # End Source File # Begin Source File SOURCE=..\Modules\yuvconvert.c # End Source File # End Target # End Project
6. Using Microsoft Visual C++, open the /PCbuild/pcbuild.dsw workspace. 7. Select the Batch Build option and say Rebuild All. By default, the EXE file and the DLLs will be saved in your /Pcbuild/ directory. Linking Dynamic Extensions to the Interpreter Now look at what you should do in order to create dynamic extension modules.
Dynamic Extensions on UNIX
The next few steps show how to build Dynamic extensions on UNIX. Step 1. Put the reference to your module in the Setup.in file. If your module references other source files, you should include them too. You might want to create a new Setup.in file in the directory containing your module.
Step 2. Copy the Makefile.pre.in file to the directory where your module is located. Step 3. Type
Next, how you can build a Dynamic Extension on Windows is illustrated. Step 1. Create a directory in the Python top-level directory. Give it the name of your module. For example, c:\python\Python-1.5.2\pimodule Step 2. Copy your modulenamemodule. c file to this directory. Step 3. Copy the files example.def, example.dsp, example.dsw, and example.mak, which are located at the /PC/example_nt directory of the standard distribution to your new
directory. Don't forget to rename the prefix of these files in order to match the name of your module. Step 4. On each file, replace the occurrences of example with your module name. Step 5. Choose the Build Menu option in order to generate your modulename.dll. A subdirectory was created underneath your working directory. This subdirectory, called Release, contains your modulename.dll. A tool created by David Ascher is very useful to create Python extension modules. It uses a UNIX Setup.in file to generate and build a Microsoft Visual C++ project. This tool is called compile.py. To use it, you just need to put your C module and the compile.py file in the same directory, and execute the tool. When fired, the program creates a MS Visual C++ project (.dsp extension) and the workspace (.dsw extension). Along with those files, it also creates a subdirectory called /pyds in which it stores the python extension module (.pyd extension). In order to use this extension in your application, the interpreter needs to be able to locate the .pyd file by looking at the sys.path's variable. compile.py is available at http://starship.python.net:9673/crew/da/Code/compile
Installing and Using Dynamic Modules
Place your module.so or module.dll in a directory that is defined by your PYTHONPATH environment variable. The site-packages directory under the lib directory is a good place to put your extension modules.
At runtime, you can add the extension module's path to sys.path. On Windows, you can place the extension module in the same directory of the python.exe file. Put the extension in the current directory when you start Python.
You won't find any difference while running dynamic modules. They act exactly the same way as the static modules that are linked to the interpreter.
Accessing Generic DLLs
Sam Rushing has created an extension module called calldll that enables Python to call any function that is part of a Windows DLL. It doesn't matter whether the DLL is a Python extension. The problem to remember is that errors caused by non-Python extension DLLs don't return exception codes but error messages. With this module you can call any function in any DLL. This means that you can do just about anything on Win32. This module includes a library that gives access to lots of the system GUI features, and a 'callback'generator for i386, which lets external functions call back into Python as if it were C. (Much of the Win32 API uses callbacks.) Along with that, you can access ODBC by directly calling functions in odbc32.dll using a wrapper module called odbc.py. The ODBC module is implemented using calldll, and it has a few extra practical pieces; code for managing data sources, installing ODBC itself, and creating and maintaining Jet (Microsoft Access) databases. It has also been tested with ODBC drivers from Oracle and Objectivity. Of course, using calldll destroys any platform or architecture independence your program may have had. You can see more details at http://www.nightmare.com/software.html.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
messages error non-Python extension dynamic link libraries (DLLs) modules calldll 2nd dynamic installing and running extension compiling and linking 2nd 3rd 4th 5th 6th 7th odbc.py objects Python embedding in non-Python applications;compiling and linking extension modules 2nd 3rd 4th 5th 6th 7th odbc.py module programming languages C extending and embedding Python 2nd 3rd 4th 5th 6th C++ extending and embedding Python 2nd 3rd 4th 5th 6th programs non-Python embedding Python objects in;compiling and linking extension modules 2nd 3rd 4th 5th 6th 7th running dynamic modules Rushing, Sam software non-Python embedding Python objects in;compiling and linking extension modules 2nd 3rd 4th 5th 6th 7th static extensions linking to interpreters 2nd 3rd tools compile.py 2nd UNIX linking static extensions to interpreters 2nd utilities compile.py 2nd Windows linking dynamic extensions to interpreters 2nd linking static extensions to interpreters
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 6. Extending and Embedding Python > SWIGThe Simple Wrapper Interface Generator
CONTINUE >
C/C++ code is easily tested because you can call C functions and libraries directly from your scripting environment. Debugging your C code also becomes easier once you use Python's interpreter. Remember that you don't need to change your C code in order to use SWIG. SWIG can integrate different C/C++ programs together by turning them into extension modules. After the extensions are created, Python can combine and use them to generate new applications. SWIG understands and parses ANSI C/C++ syntax. The output of SWIG is a fully functional scripting language module. As SWIG is designed to work with existing C/C++ code, it will be rarely necessary to change your existing programs. Your C/C++ code remains separate from your Python code. SWIG output can be freely extended and customized. Now, the most interesting thing is that you don't need to master all the details about the Python/C API in order to use the basics of SWIG to create your Python extension modules. SWIG automates the process of generating a Python extension based on the header of the functions that you want to export. Take a look at the following example and see how simple it is to generate a wrapper file. We will first create an input file, and call it helloworld.i.
Now, we will use SWIG to generate the wrapper file. We need to pass an argument to SWIG informing that the wrapper must be created for the Python language. That's because SWIG works with many
different languages.
As you can see, a wrapper file called helloworld_wrap.c was created for you. More information about SWIG can be found at the following Web pages: SWIG official Web site: http://www.swig.org SWIG Users GuideChapter 9, "SWIG and Python" : http://www.swig.org/Doc1.1/PDF/Python.pdf "Using SWIG to Control, Prototype, and Debug C Programs with Python": http://www.swig.org/papers/Py96/python96.html "Feeding a Large-scale Physics Application to Python": http://www.swig.org/papers/Py97/beazley.html "Interfacing C/C++ and Python with SWIG": http://www.swig.org/papers/PyTutorial97/PyTutorial97.pdf "The Benefits of Scripting Languages," by John Ousterhout: http://www.scriptics.com/people/john.ousterhout/scripting.html
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
generating 2nd
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 6. Extending and Embedding Python > Other Wrappers
CONTINUE >
Other Wrappers
Besides SWIG, there are other very interesting wrapper projects, such as SIP, which is specifically designed for integrating C++ class libraries with Python by generating compilable C++ code from a set of specification files that are similar to C++ header files. "SIPPython Bindings for Qt and KDE," by Phil Thompson: http://www.river-bank.demon.co.uk/software/ "Python + KDE Tutorial," by Boudewijn Rempt: http://www.xs4all.nl/~bsarempt/python/tutorial.html "SCXX (Simplified CXX) is a lightweight C++ wrapper for dealing with PyObjects," by Gordon McMillan: http://starship.python.net/crew/gmcm/scxx.html "CXXA facility for creating Python extensions in C++," by Paul F. Dubois: http://www.foretec.com/python/workshops/199811/proceedings/papers/dubois/dubois.html Note that this last document is very instructive because it shows how to create new object types in Python by using CXX.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 6. Extending and Embedding Python > Embedding
CONTINUE >
Embedding
We will now talk about how to embed Python inside other programs. Python offers a clean interface that allows embedding to occur. You might be asking yourself why would you want to do it. Well, the answer is quite simple; as a scripting language, Python can wire its interpreter into other programs to enable you to make calls to specific Python functions and execute particular Python statements from them. Those programs will have the capability to load Python scripts and execute Python services that belong to specific Python modules. You can also call Python functions directly from your C code and access the Python objects that are returned by them. In order to embed Python inside a program, you just need to use the Python APIthe Python EXE is not necessary. Implementing Callback Functions Embedding Python allows you to access and use the Python interpreter from inside your application. But what happens if you need to call back your application functions from inside Python? For this reason, it is a good practice to provide a module written in C that exposes an API related to the application. Therefore, when embedding Python within your routines, you can make your application communicate both ways with your Python program by accessing the Python extension modules. Embedding the Python Interpreter The next example adds Python functionality to a C program.
// File: embedding.c #include <stdio.h> #include <Python.h> int main(int argc, char **argv) {
Py_Initialize(); PyRun_SimpleString("print 'Hello Python World'"); printf("You are my visitor number %i", args); Py_Finalize(); return(0); }
Python provides a set of function calls that provide an interface to the Python interpreter. The most important ones are
q
Py_Initialize Initializes and allocates the internal resources of the interpreter in order to start using the API. PyRun_SimpleString Executes Python code strings in the context of the __main__ module. Each string must be a complete Python command. This high-level function reads from a character buffer and returns 0 for success and -1 when exceptions occur. Another function called PyRun_String provides more control of the code execution. The source code of this function is available in your installation in the Python/pythonrun.c file.
Tip Remember that you need to inform the new line character at the end of each command line to make sure that the interpreter validates the command.
Py_Finalize Releases the internal resources and shuts down the interpreter. You should always call this function before leaving the program. PyRun_SimpleFile Executes Python commands that are stored in a file. This function reads from a FILE pointer. Check out this other example:
Py_Initialize(); PySys_SetArgv(int argc, char **argv); PyRun_SimpleString("print 'Hello Python World'\n"); PyRun_SimpleString("print sys.argv\n"); PyFinalize(); Py_Exit(0); }
PySys_SetArgv This function sets the values for the sys.argv list.
You can access a module written in Python from C by getting a pointer to the module object as follows:
module = PyImport_ImportModule("<modulename>");
If the module hasn't been imported yet (that is, it isn't yet present in sys.modules), this function initializes the module; otherwise it simply returns the value of sys.modules["<modulename>"]. It doesn't enter the module into any namespaceit only ensures that it has been initialized and it is stored in sys.modules. You can then access the module's attributes (that is, any name defined in the module) using PyObject_GetAttrString() as follows:
It is also possible to assign values to variables in the module using the PyObject_SetAttrString() function. There is a very straightforward example of embedding Python in a C program in the file /Demo/embed/demo.c, which is part of your Python distribution source code.
Embedding on UNIX
On UNIX, you must link your C application against the Python interpreter library, which is called libpython1.5a.
When compiling the yourprogram.c into a object file (yourprogram.o), you need to specify the directory of the Python distribution. For example,
gcc -g -c yourprogram.c
Note You need to make sure that the header files required by your program are correctly installed on your system.
When compiling the object file into an executable file, you need to include the libraries and references for any extension modules embedded into the Python interpreter itself. Check the Makefile file of the Python interpreter to know the files that must be mentioned.
Listing 6.1 File: Makefile VERSION= 1.5 LIBPYTHON= $(blddir)/libpython$(VERSION).a LIBS= -lreadline -ltermcap -lcurses -lgdbm -ltk8.0 -ltcl8.0 -lX11 -ldl SYSLIBS= -lm MODLIBS= -L/usr/X11R6/lib -I/usr/local/pgsql/include -L/usr/local/pgsql/lib -lcrypt ALLLIBS= $(LIBPYTHON) $(MODLIBS) $(LIBS) $(SYSLIBS)
All the libraries found in the Makefile file are used as arguments to the function that compiles the object file, as you can see next.
-lcrypt -lreadline -ltermcap -lcurses -lgdbm -ltk8.0 -ltcl8.0 -lX11 -ld1 -lm -o yourprogram
The last step is to type make to build the application. Note In order to compile an extension module for use with the embedded python interpreter, you just need to compile the module into the executable and make sure that you call the init function for the module after initializing the interpreter.
Embedding Python in C++ You don't have to recompile your interpreter. You just need to write your main program in C++ and use a C++ compiler to compile and link your program. Embedding Python in Other Applications On Windows, Python itself is implemented in a DLL called Python15.dll. Note that the file Python.exe is a small program that calls all the routines stored in the DLL. This is a good example showing that it must be easy to embed Python because it already embeds itself. Besides all this talk about embedding Python in C and C++ applications, Python can also be embedded in other applications, such as Delphi. However, note that implicitly, the embedding process is at the C level too. Dr. Dietmar Budelsky and Morgan Martinet merged their two separate projects and created The Python for Delphi project. The purpose of this project is to provide an interface to the Python language in Delphi. This project consists of a set of components that wrap the Python15.dll into Delphi. These components let you easily execute Python scripts, create new Python modules and new Python types. You can create Python extensions as DLLs and much more. Currently, it supports Delphi versions 3, 4, and 5. The Python for Delphi project: http://www.multimania.com/marat/delphi/python.htm
NSAPI/NSAPY
A real-life example of how Python can be used by other applications is in the case of embedding Python under Netscape HTTP Servers that support the NSAPI module protocol. This marriage brings several add-ons to the Netscape Server mostly because of the general scripting capabilities acquired from the Python language. In order to do this embedding, it is necessary to use the Nsapy, which is an extension that works by embedding the interpreter within Netscape HTTP Servers that use NSAPI. NSAPIThe Netscape Server API: http://oradb1.jinr.ru/netscape/NSAPI/ "Nsapy," by Gregory Trubetskoy: http://www.ispol.com/home/grisha/nsapy/nsapy.html Example of embedding Python under a Netscape Commerce server: http://starship.python.net/crew/aaron_watters/embed/
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
C programming language extending and embedding Python 2nd 3rd 4th 5th 6th 7th C++ programming language extending and embedding Python 2nd 3rd 4th 5th 6th 7th callback functions implementing compiling extension modules creating Python extension modules 2nd 3rd 4th 5th 6th 7th embedding interpreters 2nd 3rd 4th Python objects 2nd 3rd 4th 5th 6th 7th extension modules compiling creating 2nd 3rd 4th 5th 6th 7th files Makefile functions callback implementing init() PyRun_String() implementing callback functions init() function interpreters embedding 2nd 3rd 4th Makefile file Martinet, Morgan module attributes accessing module protocols NSAPI/NSAPY 2nd modules accessing extension compiling creating 2nd 3rd 4th 5th 6th 7th Python15.dll NSAPI/NSAPY module protocol 2nd objects embedding in non-Python applications 2nd 3rd 4th 5th 6th 7th programming languages C extending and embedding Python 2nd 3rd 4th 5th 6th 7th C++ extending and embedding Python 2nd 3rd 4th 5th 6th 7th
programs non-Python embedding Python objects in 2nd 3rd 4th 5th 6th 7th protocols module NSAPI/NSAPY 2nd PyRun_String() function Python15.dll module software non-Python embedding Python objects in 2nd 3rd 4th 5th 6th 7th UNIX embedding interpreters 2nd values assigning to variables, modules variables modules assigning values to
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 6. Extending and Embedding Python > Summary
CONTINUE >
Summary
This chapter exposes the extending and embedding functionality that gives Python the credit of possessing the capability to glue applications together. Whenever you use Python code to call C code, you are extending Python. On the other hand, if you use C code to call Python code, you are embedding Python. Python has a good relationship with C because Python's interpreter is written in C, and since its beginning, the interpreter has been ready to work with extension modules. The extension modules are mostly used to add new functionality to Python when there is no other way to interface Python with a particular system or hardware. Sometimes, when Python code is inefficient, extension modules are also used to boost performance. If you need to call Python routines from inside your application, you can use the embedding functionality to have them called by your compiled language. Python provides an intuitive and clean C Application Programmers Interface (API) that exposes the interface to the Python runtime system. This API provides a great number of functions to manipulate Python objects and built-in types from C and C++. In order to use your new extension modules, you can't forget to create the initialization function of the module and the method array that assigns the internal function names with the function names that are exposed in the module's interface. The most important functions of an extension module are PyArg_ParseTuple and Py_BuildValue. They handle all the interfacing between C and Python. Both functions check the argument's type by looking at a formatting string. Tables 6.1 and 6.2 (one for each function) list all the possible formatting strings. In addition to methods, you can also export constants back to Python. You just need to bind the constant name to the module namespace dictionary. You must indicate errors in your extension module by returning NULL to the interpreter because
functions signal errors by returning NULL. You can also use exception functions defined by the Python/C API. New exceptions can be created and stored at extension module as well. Python extensions don't benefit from all the safety provided by the Python runtime system. There are a lot of things that you have to be worried about. The main thing is reference counting, which is handled by the Py_INCREF and Py_DECREF functions. It becomes harder to adjust and compile code as C++ because Python has a C-based interpreter that has some restrictions when it comes to creating extension modules using C++. Two options are available for building Python extension modules. The first one compiles and links the module into the interpreter. This option makes the module always available to the interpreter. The second option doesn't require that you recompile the interpreter because it dynamically links the modules to the system. SWIG is an automated tool create by David Beazley that is used to write interfaces between Python and existing C libraries. These interfaces can contain several single functions. The programmer doesn't have to write any special wrapping functions to provide the glue between the Python scripting language and the C functions. Besides SWIG, other applications (such as SIP and SCXX) are suitable for helping programmers wrap their C code. While embedding Python in your programs, you will have the ability to load Python scripts and execute Python services that belong to specific Python modules. You can also call Python functions directly from your C code and access the Python objects that are returned by them. In order to embed Python inside a program, you just need to use the Python APIthe Python EXE isn't necessary. When embedding Python in your C++ code, it isn't necessary to recompile Python itself using C++. In order to start the Python API service in your program, it is necessary to call the Py_Initialize function. To shutdown the Python interpreter, it is necessary to call the Py_Finalize function. Python can be easily embedded in various languages and applications, such as C++, Delphi and Netscape Servers.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 6. Extending and Embedding Python > Code Examples
CONTINUE >
Code Examples
Listing 6.1 Benchmark Extension (File benchmarkmodule.c)
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39:
#include "<Python.h>" static PyObject * benchmark_generate(PyObject *self, PyObject *args); { int index, number_of_arguments; PyObject *numberslist = NULL; PyObject *check_value = NULL; PyFloatObject *aux_float = NULL; double element_value; double minimum_value = 100; double maximum_value = 0; char *exist_check; if (!PyArg_ParseTuple (args, "OO", &numberslist, &check_value)) return NULL; if (!PyList_Check(numberslist)) { PyErr_SetString(PyExc_TypeError, "Invalid list of values !"); return NULL; } if (!PyFloat_Check(check_value)) { PyErr_SetString(PyExc_TypeError, "Invalid checking value !"); return NULL; } number_of_arguments = PyList_Size(numberslist); exist_check = "No"; for (index=0; index<number_of_arguments; index++) { aux_float = (PyFloatObject *) PyList_GetItem(numberslist, index); if (!PyFloat_Check(aux_float)) { PyErr_SetString(PyExc_TypeError, "Invalid list value !"); return NULL;
40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63:
} element_value = PyFloat_AsDouble(aux_float); if (element_value < 0 ) { PyErr_SetString(PyExc_TypeError, "The values cannot be less than 0 !"); return NULL; } if (element_value > 100 ) { PyErr_SetString(PyExc_TypeError, "The values cannot be greater than 100 !"); return NULL; } if (element_value < minimum_value) minimum_value = element_value; if (element_value > maximum_value) maximum_value = element_value; if (element_value == PyFloat_AsDouble(check_value)) exist_check = "Yes"; } return Py_BuildValue("(ffs)", minimum_value, maximum_value, exist_check );
64: } 65: 66: static PyMethodDef benchmark_methods[] = { 67: {"generate", benchmark_generate, METH_VARARGS, "Minimum Value, Maximum Value"}, 68: {NULL, NULL} 69: }; 70: 71: DL_EXPORT(void) initbenchmark() 72: { 73: Py_InitModule("benchmark", benchmark_methods); 74: } Line 9: PyFloatObject is a subtype of PyObject. Line 18: Checks whether the first argument is a list. Line 24: Checks whether the type of the second argument is a float. Line 26: Raises a TypeError exception. Line 30: Returns the list's length.
Line 60: PyFloat_AsDouble converts a Python Float into a C double. Next, you can see a small interaction with this program. To execute it, we have to pass two arguments: The first one is a list of numbers, and the second one is a float number. This program returns the minimum and maximum values from the list, along with a logical test that informs whether the float number is part of the list.
Python 1.5.2 (#0, May 30 2000, 00:16:14) [MSC 32 bit (Intel)] on win32 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam >>> import benchmark >>> benchmark.generate([1.1],1.1) (1.1, 1.1, 'Yes') >>> benchmark.generate([1,2,3],4.5) (1.0, 3.0, 'No') >>>
Wrapping C Functions By wrapping functions, you can use C code files, without changing them. Every time you feel the need to include a C source code file in your Python project, it is necessary to create a special module that wraps its functions, and to include a reference to the file in the python15.dsp. The next example wraps the functions stored in the cfunctions.c file.
Listing 6.2 File: cfunctions.c
#include <stdio.h> void display_info(char *user, char *domain, char *country) { if (country == "USA") printf("%s@%s\n", user, domain); else printf("%s@%s.%s\n", user, domain, country); } int calc_year (int f_year, int m_year, int l_year) { int result; result = ((l_year + m_year + f_year) / 3); return result; }
Listing 6.3 File: wrappermodule.c
1: #include "Python.h" 2:
3: extern void display_info(char *, char *, char *); 4: extern int calc_year(int, int, int); 5: 6: static PyObject *wrapper_display_info(PyObject *self, PyObject *args, PyObject *kwargs) 7: { 8: char *user = "None"; 9: char *domain = "None"; 10: char *country = "None"; 11: static char *keywords[] = {"user","domain","country",NULL}; 12: 13: if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|sss", keywords, &user, &domain, &country)){ 14: return NULL; 15: } 16: 17: display_info(user, domain, country); 18: return Py_BuildValue(""); 19: } 20: 21: static PyObject *wrapper_calc_year(PyObject *self, PyObject *args) { 22: int f_year, m_year, l_year, result; 23: if (!PyArg_ParseTuple(args, "iii", &f_year, &m_year, &l_year)) { 24: return NULL; 25: } 26: result = calc_year(f_year, m_year, l_year); 27: return Py_BuildValue("i", result); 28: } 29: 30: static PyMethodDef wrappermethods[] = { 31: {"display_info", wrapper_display_info, METH_VARARGS|METH_KEYWORDS}, 32: {"calc_year", wrapper_calc_year, METH_VARARGS}, 33: {NULL, NULL} 34: }; 35: 36: void initwrapper() { 37: Py_InitModule("wrapper", wrappermethods); 38: } Lines 3 and 4: Identify which functions are external to this file. Line 11: Creates a dictionary of keywords to be accepted by the function. Line 13: PyArg_ParseTupleAndKeywords() parses the Python-level parameters by accepting a third "PyObject *" parameter. Line 31: The METH_VARARGS|METH_KEYWORDS clause makes it clear that keyword elements are expected. Next, you can see a small interaction with this program. The first function builds an email address based on the
information provided. The other one calculates the average age of a family of three people based on the number of years that are passed to the function.
Python 1.5.2 (#0, May 30 2000, 00:56:46) [MSC 32 bit (Intel)] on win32 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam >>> import wrapper >>> wrapper.display_info("andre2530","aol.com","br") [email protected] >>> wrapper.calc_year(10, 30, 35) 25 >>>
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark 2002, O'Reilly & Associates, Inc. CONTINUE >
Web Development > Python Developer's Handbook > 7. Objects Interfacing and Distribution
CONTINUE >
Web Development > Python Developer's Handbook > 7. Objects Interfacing and Distribution > Object Interfacing and Distribution
CONTINUE >
Web Development > Python Developer's Handbook > 7. Objects Interfacing and Distribution > Interfacing Objects
CONTINUE >
Interfacing Objects
Currently, one of the biggest problems with both COM and DCOM architectures is that they are supported only by Windows systems. However, most operating systems have their own native way of connecting systems together at a remote procedure call level. At the time of this writing, there are some unconfirmed rumors that Microsoft is planning to create an interface to the Windows operating system using the XML-RPC protocol. This development would bring a whole new world to the Windows applications by increasing their connectivity with all the other platforms. Note that Microsoft has already produced a similar protocol called SOAP. The COM-based technologies are the focus of Microsoft's development plans for Windows, ranging from operating systems and languages to messaging and databases. Nowadays, new COM-based technologies are found in a lot of places inside your Windows system, such as the ActiveX controls and VBScript processing. OLEDB, for example, is the successor to ODBC. ODBC gives access to relational databases, whereas OLEDB provides a more versatile level of access, so that the same API can be used to retrieve data from all kinds of sources, ranging from flat text files, through Excel spreadsheets, up to ODBC databases.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Web Development > Python Developer's Handbook > 7. Objects Interfacing and Distribution > Introduction to COM Objects
CONTINUE >
components and identifying their functionality, so individual components are swappable without having to recompile the entire application. COM provides a communication mechanism that enables components to interact across a network. More importantly, COM provides location transparency to applications (if desired) that enables them to be written without regard to the location of their components. The components can be moved without requiring any changes to the application. COM is a binary standard. Any language that can cope with the binary standard can create or use COM objects. The number of languages and tools that support COM increases every day. C, C++, Java, JScript, Visual Basic, VBScript, Delphi, and PowerBuilder form just part of that growing list, which means that any one of these languages can easily interoperate with Python. Keep in mind that COM is a standard for interaction between programsan Object Request Broker service. COM is the object model that underlies most of the Microsoft technologies; here are a few of those COM applications:
q
ActiveX uses COM to provide controls. OLE uses COM to combine documents. OLEDB and ADO use COM for data access. DirectX uses COM for graphics.
Any COM-aware program is able to interact with other COM-aware programs. One program can even execute commands of the other. The program that executes the method call is called the COM server, and the program that calls the object method is called the COM client. Because COM is a Microsoft product, most applications for Windows can act as COM servers or clients. Python's support for the COM technology is included in the Python for Windows (PythonWin) extensions. COM Interfaces The COM technology is very broad and complex. Basically, it enables objects to be shared among many applications, without applications knowing the implementation details of the objects. Objects that implement the COM technology can communicate with each other without the need for knowing the others'details. COM components do business with interfaces. An interface defines functionality, but not implementation. Objects must handle the implementation. COM objects are small pieces of self-
contained software that interact with other applications by exposing well-defined, languageindependent interfaces. COM is an object model that relies heavily on interfaces. These interfaces are entirely separate from their implementations. Although COM defines the interfaces, its model doesn't provide the interface's implementation. Each object's class has the task of defining the implementations. The interfaces can be standard ones that other objects also expose, or they can be special ones that are particular to that object. A unique ID, called an IID (Interface ID), identifies each interface. IIDs use Universally Unique Identifiers (UUID). UUID is a format used for many COM IDs to allocate a unique identification string for objects. Many tools can generate unique UUIDs. As you will see later in this chapter, Python's pythoncom module has a function called CreateGuid() that generates UUID strings. In order to create an object, COM locates the required class and creates an instance of it. The concept of COM classes is identical to the other Python classes. Additionally, each COM class needs to implement two identifiers: Class ID (_reg_clsid_), which is another UUID, and Program ID (_reg_progid_), which is a identification string that must be easier to remember than the Class ID. This string is not guaranteed to be unique. In order to create an object, the programmer must specify either the progid, or the clsid. All interfaces are derived from the IUnknown interface. Therefore, they support its methods. The IUnknown interface is the base of all COM interfaces. This interface contains only three methods:
q
AddRef() and Release() are used for managing COM lifetimes, which are based on reference counts. QueryInterface() is used for obtaining a reference to one of the other interfaces that the object exposes. In other words, interfaces are obtained by using the IUnknown::QueryInterface() method.
IStream, IStorage, and IPropertyPage are examples of standard interfaces defined by COM. They define file-like operations, file system-like semantics, and how a control exposes a property page, respectively. Besides the standard interfaces, COM also enables you to define your own custom interfaces by using an Interface Definition Language (IDL). The IDispatch interface enables any COM objects to be used from a scripting environment. This interface was designed explicitly for languages that cannot use normal COM interfaces. The objects that implement this interface are known as automation objects because they expose a programmable interface that can be manipulated by another program. This interface exposes dynamic object models whose methods and properties can be determined at runtime. Basically, this interface is used whenever you are handling an object whose interface is not known at compile time, or if there is no compile time at all.
Note Note for CORBA programmers: IDispatch is equivalent to the interface repository and dynamic invocation interface that are standard parts of CORBA.
To access a method or a property of an object, you can use either late or early binding. All the examples that you see in this book use late bindings because the Python interpreter doesn't know what the object interfaces look like. It doesn't know which are the methods and properties that compound the object. It just makes the calls dynamically, according to the function names that you provide. Late bindings use the IDispatch interface to determine the object model at runtime. Python function win32com.client.Dispatch() provides this runtime facility. Most examples in this chapter use the IDispatch interface. However, the win32com.client.Dispatch() function hides many implementation details from us. Internally, Python converts the names into IDs using the internal function GetIDsOfNames(). Then, this ID is passed as an argument to the Invoke() function. You can try to improve the performance of your program by calling the Invoke() function directly. Usually, the performance gets better when names are not resolved at runtime. Just be careful to provide the right ID. If you implement this way, an early binding operation is executed. For the early bindings, we have the concept of Type Libraries, wherein the object model is exposed at compile time. In this kind of implementation, you don't call the methods and properties directly. The GetIDsOfNames() method gets an ID for the method or property that you want to use, and the Invoke() method makes the call. For example, a function call would be invoked as
Usually, you don't have to worry about this kind of implementation. You just say
YourObject.YourMethodCall()
and
YourObject.ObjectProperty
In order to implicitly call the Invoke() method without causing data type problems, the IDispatch interface assumes the data type VARIANT for all variables. That's because late bindings do not know the specific types of the parameters, whereas early bindings do. Late bindings do not know about parameters passed by reference, so no parameters are passed by reference. However, early bindings accept parameters passed by reference, and return them as tuples. COM objects can be implemented as InProc objects, which are implemented as DLLs. These objects are loaded into the calling process providing that best performance because no marshalling is required. Of course, for most objects, some marshaling will be needed to marshal Python parameters into a form that can be passed to the COM object. The other option is to implement COM objects as LocalServer/ RemoteServer objects. This kind of object is implemented as a standalone EXE, which is safer than the first option because of process isolation. COM can also be used to decide which implementation should be used. If both types of implementation are available, the caller interface is able to decide which option is the best one to choose.
The Windows Registry
All the information concerning a COM object, such as the mapping between its progid and clsid, is stored in the Windows Registry. The Windows Registry also stores the name of the DLL file of an InProc object, and the name of the EXE LocalServer object. Object security, threading models, and many other details are also stored there. Check the following link for more details about the COM specification:
Microsoft Common Object Model http://www.microsoft.com/com/resources/specs.asp ADO ActiveX Data Objects (ADO) is an automation-based interface for accessing data. This technology uses the OLE DB interface to access an extensive range of data sources, including but not limited to data provided by the ODBC. Microsoft Remote Data Service (RDS) is a component of ADO that provides fast and efficient data frameworks for applications hosted in Microsoft Internet Explorer. RDS uses data-aware ActiveX controls to provide data access programming to Web developers, who need to build distributed, dataintensive applications for use over networks. RDS is based on a client/server, distributed technology that works over HTTP, HTTPS (HTTP over Secure Sockets layer), and DCOM application protocols. ActiveX An ActiveX control is an OLE control that can live inside an HTML page; it can be simple Window objects, such as buttons, text boxes, or scrollbars. It also can be quite complicated, for example, a bar chart graph display can be an ActiveX control. An entire spreadsheet can also be a single control. Each ActiveX control has properties and reacts to external events. Its properties can be modified to change its appearance. For example, its containing program can set color and fonts. External events such as a mouse click or keyboard input can cause a control's event handler to execute. Note that the ActiveX technology is another Windows only thing, and not really any use in a cross platform environment. Microsoft's Web browser, Internet Explorer, is ActiveX-aware, meaning that Web application developers can package ActiveX components to create more dynamic content in their Web pages. ActiveX controls use COM technologies to provide interoperability with other types of COM components and services. ActiveX controls provide a number of enhancements specifically designed to facilitate distribution of components over high-latency networks and to integrate controls into Web browsers. These enhancements include features such as incremental rendering and code signing, which enables users to identify the authors of controls before allowing them to execute.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
Common Object Model (COM) 2nd 3rd IDispatch 2nd IPropertyPage IStorage IStream IUnknown 2nd interfacing objects Common Object Model (COM) 2nd 3rd 4th 5th 6th Internet browsers Internet Explorer Internet Explorer Invoke() function IPropertyPage interface IStorage interface IStream interface IUnknown interface 2nd late bindings IDispatch interface libraries Type LocalServer object methods accessing objects AddRef() IUnknown interface 2nd QueryInterface() Release() methods Microsoft Remote Data Service (RDS) models Common Object (COM) 2nd 3rd 4th 5th 6th 7th objects accessing methods and properties ActiveX Data (ADO) 2nd automation InProc interfacing and distributing Common Object Model (COM) 2nd 3rd 4th 5th 6th LocalServer performance applications improving programs
improving performance properties accessing objects QueryInterface() method RDS Registry Common Object Model (COM) object storage Release() method Remote Data Service (RDS) services Microsoft Remote Data (RDS) software improving performance speed applications improving storage Common Object Model (COM) objects, Windows Registry Type Libraries Universally Unique Identifiers (UUIDs) UUID win32.com.client.Dispatch() function Windows Registry Common Object Model (COM) object storage
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 7. Objects Interfacing and Distribution > Implementing COM Objects in Python
CONTINUE >
directly. Instead, they usually use the win32com wrapper classes and functions written in Python to provide a nice, programmable interface. win32com.client Provides support for COM clients (for example, using Python to start Microsoft Excel and create a spreadsheet). The COM client support enables Python to manipulate other COM objects via their exposed interfaces. All client-side IUnknown-derived objects, including IDispatch, are supported. win32com.server Provides support for COM servers (for example, creating and registering a COM server object in Python and using a language such as Visual Basic or Delphi to access the Python objects). The COM server support enables Python to create COM servers, which can be manipulated by another COM client. All server-side IUnknown-derived objects are supported. win32com.axscript This is the ActiveX Scripting implementation for Python. win32com.axdebug This is the Active Debugging implementation for Python. win32com.mapi Provides utilities for working with MAPI and the Microsoft Exchange Server. Talking to Windows Applications The COM technology has been part of the Windows world for a long time. The COM genealogy can be traced back to DDE (Dynamic Data Exchange). DDE was the first device for transferring data between various applications in a multi-tasking computer. After some time, DDE was expanded to Object Linking and Embedding (OLE)note that COM was invented as part of OLE. The creation of the Visual Basic Extensions (VBXs) enhanced the OLE technology for visual components, originating a new standard called OLE2, which was based on top of COM. Soon, the OLE2 technology became more integrated with COM, which is a generalpurpose mechanism. Nowadays, COM is mostly known, in part, because of the ActiveX technology. Professional applications such as Microsoft Office and the Netscape browser enable you to control their objects using COM. Therefore, programs written in Python can be easily used to control those applications. COM passes string objects as Unicode characters. Before using these objects in Python, it's necessary to convert them to strings. The Python-2.0 Unicode string type is not the same as the string type, but it is easy to convert between the two. PythonWin comes with a basic COM browser (Python Object browser). This program helps you to identify the current objects in your system that implement COM interfaces. To run the browser, select it from the PythonWin Tools menu, or double-click on the file win32com\client\combrowse.py. Note that there are other COM browsers available, such as the one that comes with the Microsoft Visual C++.
If you study the file \python\win32com\servers\interp.py, which is installed as part of your PythonWin distribution, you will learn how to implement a very simple COM server. This server exposes the Python interpreter by providing a COM object that handles both the exec and eval methods. Before using this object, register it by running the module from Python.exe. Then, from Visual Basic, use CreateObject('Python.Interpreter') to initialize the object, and you can start calling the methods. Word and Excel Let's quit talking and get to some practicing. Our objective here is to open and manipulate Microsoft applications from Python. The first thing that you need to do is to import the COM client and dispatch the right object. In the next example, a variable is assigned a reference to an Excel application:
The following does the same thing, but this time the reference is to a Word application.
>>> wd = win32com.client.Dispatch("Word.Application")
Excel.Application and Word.Application are the Program IDs (progid), which are the names of the objects for which you want to create an instance. Internally, these objects have a Class ID (clsid) that uniquely registers them in the Windows Registry. The matching table between progids and clsids is stored in the Windows Registry and the matching is performed by the COM mechanism. It is not an easy job to identify an application progid, or to find out object methods and attributes. You can use COM browsers to see what applications have COM interfaces in your system. For the Microsoft Products, you can take a look at the documentation; it is a good source of information. Not necessarily every COM object implements the same interface. However, there are similarities. For example, if the previous assignments have just created the objects and you want to make them visible, you have to type
# Sets the visible property for the Excel application # Sets the visible property for the Word application
To close both programs and release the memory, you need to say
These were simple examples of implementing COM clients in Python. Next, we will see how to implement a Python COM server by creating a Python interface that exposes an object. The next block of code registers the interface in the Windows Registry. Note that every new COM object that you create must have a unique clsid, but you don't have to worry about it. The complex algorithm that works behind the scenes is ready to generate a unique identification, as shown here:
Your COM server is defined next. You have to execute the program in order to make the COM object available in the system. Store it on a file, and double-click on it.
1: class TaxApplication: 2: _public_methods_ = ['PAtax'] 3: _reg_progid_ = "Tax.Application" 4: _reg_clsid_ = "{D2DEB6E1-3C6D-11D4-804E-0050041A5111}" 5: 6: def PAtax(self, amount, tax=0.07): 7: return amount + (amount * tax) 8: 9: if __name__=='__main__': 10: print "Registering COM server" 11: import win32com.server.register 12: win32com.server.register.UseCommandLine(TaxApplication)
Line 3: Defines the name that the COM client application must use to connect to the object. Line 4: Defines the unique Class ID (clsid) used by the object. Line 12: Registers the TaxApplication class. In order to test the program, we need to have an external COM client. Let's use the Visual Basic for Applications Editor, which is present in both Excel and Word. Open your Microsoft application, type ALT+F8 in the Macro dialog box, and select the option that creates a macro. Now, you need to type the following block of code:
Sub Tax() Set TaxApplication = CreateObject("Tax.Application") newamount = TaxApplication.PAtax(100) MsgBox newamount Set TaxApplication = Nothing End Sub
Now, if you press F5, Visual Basic should display a message box showing the result of our simple tax operation, which, in our case, is 107. To unregister your COM object you can either pass the argument --unregister when calling your script, or you can use the following line of code inside your Python program:
>>> win32com.server.register.UnregisterClasses(TaxApplication)
A very comprehensive example of using Microsoft Word and Excel is stored in the testMSOffice.py file, which is part of your PythonWin distribution. It's worth checking out!!!
Word
The following code implements a simple wrapper for the Microsoft Word Application. To test it you need to create a Word document and replace its path in the code. The program will open this file, replace the first occurrence of the string "#name#" within the file, add a small bit of text to the end of the line, and print the file.
import win32com.client False = 0 True = -1 wdLine = 5 class WordApp: def __init__(self): self.app = win32com.client.Dispatch("Word.Application") def open(self, document_file): self.app.Documents.Open(document_file) def replace(self, source_selection, new_text): self.app.Selection.HomeKey(Unit=wdLine) self.app.Selection.Find.Text = source_selection self.app.Selection.Find.Execute() self.app.Selection.TypeText(Text=new_text) def addtext(self, new_text): self.app.Selection.EndKey(Unit=wdLine) self.app.Selection.TypeText(Text=new_text) def printdoc(self): self.app.Application.PrintOut() def close(self): self.app.ActiveDocument.Close(SaveChanges =False) worddoc = WordApp() worddoc.open(r"s:\ template.doc") worddoc.replace("#name#", "Andre Lessa") worddoc.addtext(" What do you want to learn ?") worddoc.printdoc() worddoc.close
If you type in the name of the object's attribute that accesses the Dispatch method, you get as a result, the COM object name:
This object is an example of a dynamic dispatch object. The provided name indicates that the object is a generic COM object, and affirms that Python doesn't know anything about it, except the name that you used to create it. All the information about this object is built dynamically. Besides dynamic dispatches, you can also use static dispatches, which involve the generation of a .py file that contains support for the specific COM object. In CORBA speak, this is called stub generation, or IDL compilation.
In order to generate the Python files that support a specific COM object, you need to execute win32com\client\makepy.py. A list of Type Libraries will be displayed. Select one (for example, 'Microsoft Word 8.0 Object Library') and click OK. You can also call the makepy.py program directly from the command prompt by typing makepy.py "Microsoft Word 8.0 Object Library". Now, Python knows exactly how to handle the interfaces before invoking the COM object. Although, you can't see any differences, you can check that Python really knows something else now by querying the COM object:
>>> import win32com.client >>> wd=win32com.client.Dispatch("Word.Application") >>> wd <win32com.gen_py.Microsoft Word 8.0 Object Library._Application>
Note that Python knows the explicit type of the object now. All the compiled information is stored in a file in the win32com/gen_py directory. You probably won't understand the filename because it is encoded. Actually, you don't need to use this file at all. All the interface information is made available via win32com.client.Dispatch and win32com.client.constants. If you really need to identify the name of the module that was generated, you can use the win32com.client.gencache module. This module has two functions: GetModuleForCLSID and GetModuleForProgID that return Python module objects you can use in your code. makepy.py also automatically installs all generated constants from a library of types in an object called win32com.clients.constants. After creating the object, all the constants become available to you. In the previous example, we had to initialize the constant wdLine, because the constants were not available. Now, after running makepy.py, you can replace the line
self.app.Selection.EndKey(Unit=wdLine)
with
self.app.Selection.EndKey(Unit=win32com.clients.constants.wdLine)
wdLine = 5
The next example uses the wdWindowStateMaximize constant to maximize Microsoft Word:
Excel
Next, we'll see how to create COM clients using Microsoft Excel. The principle is very simple. Actually, it is the same one used previously for wrapping Microsoft Word, as it is demonstrated in the following example.
Note that we have to change the Visible property in order to see the Excel application. The default behavior is to hide the application window because it saves processor cycles. However, the object is available to any COM client that asks for it. As you can see in the example, Excel's progid is Excel.Application. After you create the Excel object, you are able to call its methods and set its properties. Keep in mind that the Excel Object Model has the following hierarchy: Application, WorkBook, Sheet, Range, and Cell. Let's play a little with Excel. The following statements write to the workbook:
>>> excelapp.Range("A1:C1").Value = "Hello", "Python", "World" >>> excelapp.Range("A2:A2").Value = 'SPAM! SPAM! SPAM!'
>>> excelapp.Range("A1:C1").PrintOut()
What about entering date and time information? The following examples will show you how to set the Date/Time format for Excel cells. First, call Excel's time function:
The AutoFit() function is required in order to display the information, instead of showing "#######". Now, use Python to set the time you want:
Note that the Cells() structure works like a numeric array. That means that instead of using Excel's notation of letters and numbers, you need to think of the spreadsheet as a numeric matrix. Visual Basic In order to implement a COM object using Python you need to implement a Python class that exposes the functionality to be exported. It is also necessary to assign two special attributes to this class, as required by the Python COM implementation. The first attribute is the Class ID (_reg_clsid_). This attribute must contain a UUID, which can be generated by calling the pythoncom.CreateGuid() function. The other attribute is a friendly string that you will use to call the COM object (_reg_progid_), as follows:
_public_methodsA list of all method names that you want to publicly expose to remote COM clients. _public_attrsA list of all attribute names to be exposed to remote COM clients. _readonly_attrsA list of all attributes that can be accessed, but not set. This list should be a subset of the list exposed by _public_attrs.
After creating the class, you need to register your COM object. The general technique is to run the module that implements the COM object as a script, in order to register the object:
Notice that you need to inform the class object, and not a class instance. After the UseCommandLine() function has been successfully executed, the following message is returned by the Python interpreter:
Registered: COMCALCSERVER.VERSION1
When you have your COM object up and running, any automation-capable language, such as Python, Visual Basic, Delphi, or Perl, can use it. The following example is a complete program that implements a calculator. First, you need to collect the unique IDs for your class:
Python 1.5.2 (#0, Apr 13 1999, 10:51:12) [MSC 32 bit (Intel)] on win32 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam >>> import pythoncom >>> print pythoncom.CreateGuid() <iid:{C76BEA60-3B39-11D4-8A7C-444553546170}>
After informing the new clsid value to the _reg_clsid_ attribute, we have the following program:
# File: comcalcserver.py class COMCalcServer: _reg_clsid_ = '{C76BEA61-3B39-11D4-8A7C-444553546170}' _reg_progid_ = 'COMCALCSERVER.VERSION1' _public_methods_ = ['mul','div','add','sub'] def mul(self, arg1, arg2): return arg1 * arg2 def div(self, arg1, arg2): return arg1 / arg2 def add(self, arg1, arg2): return arg1 + arg2 def sub(self, arg1, arg2): return arg1 - arg2 if __name__ == '__main__': import win32com.server.register win32com.server.register.UseCommandLine(COMCalcServer)
Make sure that all methods are included in the _public_methods_. Otherwise, the program will fail. Now, go to the DOS prompt and execute the program to register the COM object:
To create the Visual Basic COM client, you need to create a Visual Basic Form that contains all the implementation details (see Figure 7.1).
Figure 7.1. A design for creating the Visual Basic Form.
Most of the time, the initialization steps are stored in the Form_Load section in order to be executed when the application starts:
Remember to always deallocate the objects before exiting the application. It's good practice to do it in the Form_Unload section:
Set COMCalcServer = Nothing Public COMCalcServer As Object Private Sub Form_Unload(Cancel As Integer) Set COMCalcServer = Nothing End Sub Sub InitCOMCalcServer() Set COMCalcServer = CreateObject("COMCALCSERVER.VERSION1") Exit Sub End Sub
Private Sub Command1_Click() Dim result As Double result = COMCalcServer.Mul(Val(Text1), Val(Text2)) MsgBox Text1 & "*" & Text2 & "=" & Str(result) End Sub Private Sub Command2_Click() Dim result As Double result = COMCalcServer.Div(Val(Text1), Val(Text2)) MsgBox Text1 & "/" & Text2 & "=" & Str(result) End Sub Private Sub Command3_Click() Dim result As Double result = COMCalcServer.Add(Val(Text1), Val(Text2)) MsgBox Text1 & "+" & Text2 & "=" & Str(result) End Sub Private Sub Command4_Click() Dim result As Double result = COMCalcServer.Sub(Val(Text1), Val(Text2)) MsgBox Text1 & "-" & Text2 & "=" & Str(result) End Sub Private Sub Form_Load() Text1 = 0 Text2 = 0 Command1.Caption = "Mul" Command2.Caption = "Div" Command3.Caption = "Add" Command4.Caption = "Sub" InitCOMCalcServer End Sub
While executing the application (see Figure 7.2), your Visual Basic application will be talking to the Python COM object behind the scenes.
Figure 7.2. A Visual Basic executable running.
The next example is based on the previous one. This one implements a callback function. The VB program calls a Python function that clearly manipulates the Visual Basic Form object. You need to add or replace the following functions in the Visual Basic code:
Sub InitCOMCalcServer() Set COMCalcServer = CreateObject("COMCALCSERVER.VERSION2") Exit Sub End Sub Private Sub Form_Load() Text1 = 0 Text2 = 0 Command1.Caption = "Mul" Command2.Caption = "Div" Command3.Caption = "Add" Command4.Caption = "Sub" InitCOMCalcServer COMCalcServer.updatecaption Me End Sub
The following new function must be created in the Python code, too. The VB function call uses the keyword Me to send a reference of the Form object to Python's updatecaption() method:
The following code is a full replacement to be used with this example. Remember to create a new _reg_clsid_ for this new example.
# File: comcalcserver2.py class COMCalcServer: _reg_clsid_ = '{ C76BEA64-3B39-11D4-8A7C-444553546170} ' _reg_progid_ = 'COMCALCSERVER.VERSION2' _public_methods_ = ['mul','div','add','sub', 'updatecaption'] def mul(self, arg1, arg2): return arg1 * arg2 def div(self, arg1, arg2): return arg1 / arg2 def add(self, arg1, arg2): return arg1 + arg2 def sub(self, arg1, arg2): return arg1 - arg2 def updatecaption(self, object): import win32com.client Form = win32com.client.Dispatch(object) Form.Caption = "Python COM Routine is Active" if __name__ == '__main__': import win32com.server.register win32com.server.register.UseCommandLine(COMCalcServer)
Every script that defines a COM class can be used to unregister the class, too. Python automatically knows that, when you pass the argument --unregister to the script, you want to remove all the references to this class from the Windows Registry.
Whenever you have a Python method as part of a COM server interface that returns a number or a string, as shown in the next few lines of code:
def GetNumber(self): return 25 def GetString(self, name): return 'Your name is %s'% name
The COM client written in Visual Basic must handle the methods as follows
Dim num as Variant num = Server.GetNumber Dim str as Variant str = Server.GetString("Andre") MsgBox str
Python and Unicode do not really work well together in the current version of Python. All strings that come from COM will actually be Unicode objects rather than string objects. In order to make the previous code work in a COM environment, the last line of the GetString() method must become
The conversion of the "name" to "str(name)" forces the Unicode object into a native Python string object. In Python-2.0, if the win32com stuff starts using native Python Unicode strings, the str() call will cause the Unicode string to be reencoded in UTF8.
Handling Lists and Tuples
When you have a Python method as part of a COM server interface that returns a list or a tuple, as illustrated in the next example:
The COM client written in Visual Basic must handle the method as follows:
Dim arry as Variant arry = Server.GetList Debug.Print UBound(arry) For Each item in arry Debug.Print item Next
Delphi Using Delphi to implement a COM client is very similar to using Visual Basic. First, you need to register the COM class. The following code is similar to the one used for the Visual Basic example.
_reg_progid_ = 'COMCALCSERVER.VERSION1' _public_methods_ = ['mul','div','add','sub'] def mul(self, arg1, arg2): return arg1 * arg2 def div(self, arg1, arg2): return arg1 / arg2 def add(self, arg1, arg2): return arg1 + arg2 def sub(self, arg1, arg2): return arg1 - arg2 if __name__ == '__main__': import win32com.server.register win32com.server.register.UseCommandLine(COMCalcServer)
Now, you need to create a Delphi form to support all the COM client activities (see Figure 7.4).
Figure 7.4. Delphi design: A form with three Edit boxes and four buttons.
unit Calcform; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, OLEAuto;
type TForm1 = class(TForm) Button1: TButton; Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Button2: TButton; Button3: TButton; Button4: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; COMCalcServer: Variant; implementation { $R *.DFM} procedure TForm1.FormCreate(Sender: TObject); begin try COMCalcServer := CreateOleObject('COMCALCSERVER.VERSION1'); Form1.Caption := 'Python COM Routine is Active'; Edit1.text := ''; Edit2.text := ''; Edit3.text := ''; Button1.Name := 'mul'; Button2.Name := 'div'; Button3.Name := 'add'; Button4.Name := 'sub'; except MessageDlg('An error has happened!', mtError, [mbOk],0); Application.Terminate; end; end; procedure TForm1.Button1Click(Sender: TObject); var tmp1float, tmp2float : Real;
tmp3string : String; begin tmp1float := StrToFloat(Edit1.text); tmp2float := StrToFloat(Edit2.text); tmp3string := FloatToStr(COMCalcServer.mul(tmp1float, tmp2float)); Edit3.text := tmp3string; end; procedure TForm1.Button2Click(Sender: TObject); var tmp1float, tmp2float : Real; tmp3string : String; begin tmp1float := StrToFloat(Edit1.text); tmp2float := StrToFloat(Edit2.text); tmp3string := FloatToStr(COMCalcServer.div(tmp1float, tmp2float)); Edit3.text := tmp3string; end; procedure TForm1.Button3Click(Sender: TObject); var tmp1float, tmp2float : Real; tmp3string : String; begin tmp1float := StrToFloat(Edit1.text); tmp2float := StrToFloat(Edit2.text); tmp3string := FloatToStr(COMCalcServer.add(tmp1float, tmp2float)); Edit3.text := tmp3string; end; procedure TForm1.Button4Click(Sender: TObject); var tmp1float, tmp2float : Real; tmp3string : String; begin tmp1float := StrToFloat(Edit1.text); tmp2float := StrToFloat(Edit2.text); tmp3string := FloatToStr(COMCalcServer.sub(tmp1float, tmp2float)); Edit3.text := tmp3string; end; end.
After compiling and running the application, you should see the interface shown in Figure 7.5.
Figure 7.5. Delphi Calculator Application.
Last updated on 1/30/2002 Python Developer's Handbook, 2002 Sams Publishing < BACK Make Note | Bookmark CONTINUE >
creating clients, Excel 2nd 3rd importing closing Excel and Word code calculator object 2nd 3rd 4th 5th 6th Common Object Model (COM) 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th creating Common Object Model (COM) clients Excel 2nd 3rd Python interfaces to expose objects 2nd data transferring between applications Date/Time format setting 2nd Delphi programming language implementing Common Object Model (COM) objects 2nd disabling registration Common Object Model (COM) objects Dispatch method dispatches static distributing objects Common Object Model (COM) 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th dynamic dispatch object editing Visible property Excel opening and manipulating from Python 2nd 3rd 4th 5th 6th exiting Excel and Word exposing objects, creating Python interfaces 2nd finding generated modules formats Date/Time setting 2nd functions AutoFit() Cells() Pythoncom.CreateGuid() generating modules identifying Hammond, Mark handling numbers 2nd strings 2nd identifying
generated modules implementing objects Common Object Model (COM) 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th Python Common Object Model (COM) server 2nd wrappers Word 2nd importing Common Object Model (COM) client interfacing objects Common Object Model (COM) 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th libraries makepy.py module methods Dispatch PrintOut() models Common Object (COM) 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th modifying Visible property modules generated identifying makepy.py win32.com.client.gencache modules numbers handling 2nd objects calculator source code 2nd 3rd 4th 5th 6th dynamic dispatch exposing, creating Python interfaces 2nd interfacing and distributing Common Object Model (COM) 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th PrintOut() method programming languages Delphi implementing Common Object Model (COM) objects 2nd Visual Basic (VB) implementing Common Object Model (COM) objects 2nd 3rd 4th 5th programs Excel opening and manipulating from Python 2nd 3rd 4th 5th 6th transferring data between win32all win32com 2nd 3rd Word opening and manipulating from Python 2nd 3rd 4th 5th 6th
properties Visible changing Pythoncom.CreateGuid() function quitting Excel and Word searching generated modules servers Python Common Object Model (COM) implementing 2nd setting Data/Time format 2nd software Excel opening and manipulating from Python 2nd 3rd 4th 5th 6th transferring data between win32all win32com 2nd 3rd Word opening and manipulating from Python 2nd 3rd 4th 5th 6th source code calculator object 2nd 3rd 4th 5th 6th static dispatches Stein, Greg strings handling 2nd testing Python interfaces 2nd wrappers Word transferring data between applications transporting values tuples tuples transporting values turning off registration Common Object Model (COM) objects unregistering Common Object Model (COM) objects values transporting tuples Visible property changing Visual Basic (VB) programming language implementing Common Object Model (COM) objects 2nd 3rd 4th 5th win32.com.client.gencache module win32all package
win32com package 2nd 3rd Windows transferring data between applications Word opening and manipulating from Python 2nd 3rd 4th 5th 6th wrappers Word implementing 2nd
2002, O'Reilly & Associates, Inc.
Web Development > Python Developer's Handbook > 7. Objects Interfacing and Distribution > Distributing Objects with Python
CONTINUE >
The Inter-Language Unification system (ILU) is a free and stable multi-language object interface system, whose interfaces hide implementation distinctions between different languages, address spaces, and operating system types. ILU can be used to build multilingual, object-oriented class libraries with well-specified, language-independent interfaces. It can also be used to implement distributed systems and to define and document interfaces between the modules of nondistributed programs. ILU interfaces can be specified in either the OMG's CORBA Interface Definition Language (OMG IDL) or ILU's Interface Specification Language (ISL). ILU is primarily about interfaces between modules of program structure. Each module encapsulates the part of a program that has high adhesion internally and low connection to other parts of the program. The main goal of ILU is to create object-oriented interfaces that can communicate with those modules. ILU does all the translating and communicating necessary to use all kinds of modules in a single program. Its mechanism optimizes calls across module interfaces to involve only what it is necessary for the calling and called modules to interact. The notion of a module should not be confused with the independent concept of a program instance, which is translated as a combination of code and data running in one memory image, such as the UNIX processes. ILU standardizes many of the issues involved in providing proper inter-module independence, such as memory management and error detection and recovery strategies. ILU also includes an implementation of the Object Management Group's CORBA Internet Inter-Orb Protocol (IIOP), and can be used to write CORBA services or clients, as well. ILU provides a standard notation to write its interfacesISL, which stands for Interface Specification Language. ISL is a declarative language, which can be processed by computer programs that enables you to define exceptions, constants, object and non-object types. Next, you have a sample of what ISL looks like:
INTERFACE CalcMachine; EXCEPTION DivideByZero; TYPE Calculator = OBJECT METHODS SetValue (v : REAL), GetValue () : REAL, Divide (v : REAL) RAISES DivideByZero END END;
ILU provides a program, islscan, which can be used to check the syntax of an ISL specification, parse the specification, and summarize it to standard output. After you've defined an interface, you then need to supply an implementation of your module, which can be done in any language supported by ILU.
The program python-stubber is used to read an ISL file, and generate all the Python code that is required to support the ISL interface. One of the files generated is 'Interface.py', which contains the definitions of all the Python types for that interface:
% python-stubber CalcMachine.isl client stubs for interface "CalcMachine" to CalcMachine.py server stubs for interface " CalcMachine " to CalcMachine__skel.py %
To provide an implementation of your interface, subclass the generated Python class for the Calculator class:
# CalculatorImpl.py import CalcMachine, CalcMachine__skel class Calculator (CalcMachine__skel.Calculator): def __init__ (self): self.value = 0.0 def SetValue (self, value): self.value = value def GetValue (self): return self.value def Divide (self, value): try: self.value = self.value / value except ZeroDivisionError: raise CalcMachine.DivideByZero
Each instance of a CalculatorImpl.Calculator object inherits from CalcMachine__skel.Calculator, which in turn inherits from CalcMachine.Calculator. Each has an instance variable called value, which maintains a running total of the accumulator for that instance. We can create an instance of a CalcMachine.Calculator object by simply calling CalculatorImpl.Calculator(). A very simple program to demonstrate the use of the CalcMachine module is listed next. To run this program, you have to type the command python divide.py <NUMBER_TO_DIVIDE>.
# File: divide.py import CalcMachine, CalculatorImpl, sys, string def main (argv): calc = CalculatorImpl.Calculator() if not calc: error("Error creating the calculator") calc.SetValue (10.0) divisor = string.atof(argv[1]) calc.Divide(divisor) print "the division result is", calc.GetValue() sys.exit(0) main(sys.argv)
ILU also supports the use of the interface definition language OMG IDL, defined by the Object Management Group (OMG) for its Common Object Request Broker Architecture (CORBA). That kind of support allows more programmers to easily use ILU because OMG's IDL uses a syntax similar to C++. However, because CORBA doesn't implement some of the concepts found in ILU, programmers can't implement all types of ILU interface using OMG IDL. ILU is available for free at ftp://ftp.parc.xerox.com/pub/ilu/ilu.html Using ILU with Python: A Tutorial ftp://parcftp.parc.xerox.com/pub/ilu/misc/tutpython.html CORBA Binding and Implementation The Object Request Broker (ORB) is the mechanism that lets objects transparently make requests toand receive fromother objects located locally or remotely. The ORB is the middleware that establishes the client/server relationship between objects.
Using an ORB, a client object can transparently invoke a method on a server object, which can be on the same machine or across a network. The ORB intercepts the call and is responsible for finding an object that can implement the request, pass it the parameters, invoke its method, and return the results. The client does not have to be aware of where the object is located, its programming language, its operating system, or any other system aspects that are not part of an object's interface. The client is not aware of the mechanisms used to communicate with, activate, or store the server objects. The ORB serves as the foundation for building distributed object applications. Note that CORBA can short circuit requests to objects in the same address space, as ILU and COM can, if the implementation supports this. The ORB component, or CORBA, is a set of specifications defining the ways software objects should work together in a distributed environment. The organization that drives the specifications, the Object Management Group (OMG), has hundreds of members representing a major portion of the software industry. The members work together to propose, review, and finally adopt a set of specifications to enable software objects to be developed independently and yet work together in a harmonic fashion. The fundamental piece of CORBA is the ORB, or Object Request Broker. The ORB can be viewed like a channel carrying objects between the clients (those that consume the objects) and the servers (those that produce the objects). The consumers are provided with object interfaces, which are defined using a language called the Interface Definition Language. The detailed implementation of the objects by the producers is totally shielded from the consumers. The ORB is usually just a library that the program links to that marshals object requests. The promised benefits of making the software objects from different vendors publicly known made those vendors highly endorse OMG's specifications. At the most basic level, CORBA is a standard for distributed objects. CORBA enables an application to request that an operation be performed by a distributed object and that the results of the operation be returned to the application making the request. The application communicates with the d