[Python-Dev] Type checks of instance variables
Andy Robinson
andy@reportlab.com
Wed, 10 Oct 2001 22:58:52 +0100
> class Color(object):
> __slots__ =TypedSlots({ "r":(unsignedByte,unsignedByte(0),
> "g":(unsignedByte,unsignedByte(0),
> "b":(unsignedByte,unsignedByte(0),
> "name":str})
>
This sounds great. In fact, it's almost exactly
what we have been trying to do in reportlab/graphics for
the last six months: a graphical widget hierarchy
which has to check the type of every assignment
and maybe trigger recalculations, because it supports
a GUI. It was one of the few occasions when I wished I
was using Delphi instead of Python :-) Reportlab would
certainly be interested in a standardised framework for
property-checking.
Let me throw in a few more ideas:
(1) __slots__ could hold optional attribute doc strings
(2) 'one of a list' is a mightily useful type,
and we have GUIs that can infer enough from this
to build smart editing interfaces.
(3) frequently you want the __slots__ for a class
to 'inherit' from a parent, which we do by allowing
one to pass in the parent's class; it then looks
for the __slots__ in that as a starting point.
(4) you may also sometimes want to delete things
from the __slots__ in a derived class, and to reduce
visibility.
(5) things can get slow. I'm also wondering if support
for type-checking classes could be enhanced by a C
extension, so that if one stuck to a basic bunch of types,
the penalty of checking every attribute assignment
would not be too great. It would still need to
call out to Python if the 'checking function' was
written in Python.
Here's one of our classes:
class Marker(Widget):
'''A polymorphic class of markers'''
_attrMap = AttrMap(BASE=Widget,
kind = AttrMapValue(
OneOf(None, 'Square', 'Diamond',
'Circle', 'Cross', 'Triangle', 'StarSix',
'Pentagon', 'Hexagon','Heptagon', 'Octagon',
'FilledSquare','FilledCircle', 'FilledDiamond',
'FilledCross','FilledTriangle','FilledStarSix',
'FilledPentagon', 'FilledHexagon', 'FilledHeptagon',
'FilledOctagon', 'Smiley'),
desc='marker type name'),
size = AttrMapValue(isNumber,desc='marker size'),
x = AttrMapValue(isNumber,desc='marker x coordinate'),
y = AttrMapValue(isNumber,desc='marker y coordinate'),
dx = AttrMapValue(isNumber,desc='marker x coordinate
adjustment'),
dy = AttrMapValue(isNumber,desc='marker y coordinate
adjustment'),
angle = AttrMapValue(isNumber,desc='marker rotation'),
fillColor = AttrMapValue(isColorOrNone, desc='marker
fill colour'),
strokeColor = AttrMapValue(isColorOrNone, desc='marker
stroke colour'),
strokeWidth = AttrMapValue(isNumber, desc='marker stroke
width'),
)
Regards,
Andy Robinson
CEO/Chief Architect, Reportlab Inc.