ANN: C-Python 2.3.3 Patch to Enable Python Function Subclassing - X1.0
A C-Python 2.3.3 Patch to Enable Python Function Subclassing. Experimental Version 1.0 The source code patch and a recompiled python23.dll for win32 can be found at: http://www3.telus.net/len_l/Function_Subclassing.html md5 sums: 05e7af6f007c02d3100ca4e5794bd390 *FS-src-X1-0.tgz (size 64,102 bytes) 9288762a9d2d714db55dae9adc6d844b *FS-win32-bin-X1-0.zip (size 500,118 bytes) Requirements: ------------ For the source code patch the Python 2.3.3 final source code available at www.python.org and a compatible C compiler. For the win32 binary the Windows version of Python 2.3.3 . Introduction ------------ This is an experimental patch which contains modified python interpreter source code files that permit function subclassing. The python def statement is also extended to simplify creation of subclass instances. Eg.: from types import FunctionType class FunctionSubType(FunctionType): def __call__(self, *args, **kwds): print 'Hello' return super(FunctionSubType, self).__call__(*args, **kwds) def (FunctionSubType) fn(x): # optional '(<class>)' gives subclass return 2*x fn(12) # prints 'Hello' then returns 24 The optional class specifier works with any expression that evaluates to a callable accepting the same five arguments as types.FunctionType. The parenthesis are mandatory. The above syntax was chosen because it is easy to implement. Why Function subclassing? ----------------------- Function subclassing simplifies special method creation. Normally this is done using wrapper classes like staticmethod. The following is the subclass equivalent: from __future__ import division from types import FunctionType class staticfunction(FunctionType): def __get__(self, object, type): return self # Using it is simple: # I know this example would be better done with a class method, but # it is just a simple example. :-) class Vector2(object): def __init__(self, x, y): self.x = x self.y = y def (staticfunction) Normal2(x, y): # Special constructor length = (x**2 + y**2)**0.5 return Vector2(x/length, y/length) One can write a static method mixin: class StaticMixin(object): """Make a function a static method""" def __get__(self, object, type): return self class PosFunction(FunctionType): """Ensure all arguments are positive numbers""" def __call__(self, *args): for i in args: if i < 0: raise TypeError, "Requires positive number arguments" return super(PosFunction, self).__call__(*args) class StaticPosIntFunc(StaticMixin, FunctionType): pass ... class Vector(object): ... def (StaticPosIntFunc) Normal2(x, y): ... It is a matter of opinion whether or not this approach is more elegant than using wrapper classes. The best way to decide is to try it yourself. Enjoy. Lenard Lindstrom <len-l@telus.net>
participants (1)
-
Lenard Lindstrom