class variable declarations...

Michele Simionato mis6 at pitt.edu
Mon Jun 16 19:42:31 CEST 2003


Alan Kennedy <alanmk at hotmail.com> wrote in message news:<3EEDD08E.C973E017 at hotmail.com>...
> Lee John Moore wrote:
> 
> > My biggest mental block with python seems to be undeclared variables.  A
> > declaration block alone is handy for reference.  Statically typed
> > languages have really messed me up.  Is there a therapy group for
> > refugees?  ;-)
> 
> How about this, using new style classes:-
> 
> class SpeedTouchComm(object):
>     "Interface with the SpeedTouch router"
>     
>     __slots__ = ['connect', 'uid', 'pwd', 'rtuid', 'rtpwd']
>     
>     def __init__(self, connect, uid, pwd, rtuid, rtpwd):
>         self.connect = connect
>         self.uid = uid
>         self.pwd = pwd
>         self.rtuid = rtuid
>         self.rtpwd = rtpwd
>         self.namenotinslots = ''
> 
> >>> o = SpeedTouchComm(1,2,3,4,5)
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
>   File "<stdin>", line 12, in __init__
> AttributeError: 'SpeedTouchComm' object has no attribute 'namenotinslots'
> >>>
> 
> There are more sophisticated ways to manipulate object instances and data, for
> example using descriptors or __metaclasses__. But I think that this mostly
> solves your difficulty.
> 
> HTH,

A recent thread (google is your friend) pointed out that __slots__ should 
NOT be used as a way of declaring variables.

It is much better if you use descriptors or metaclasses. Here is
a (little tested) solution:

 class UndeclaredNameError(Exception): pass
 
 class WithDeclaredNames(type):
    def __init__(cls,name,bases,dic):
        declared=getattr(cls,'declared')
        def setattr(self,k,v):
            if k in declared:
                object.__setattr__(self,k,v)
            else:
                raise UndeclaredNameError(k)
        if declared is not None: cls.__setattr__=setattr


class SpeedTouchComm(object):
    "Interface with the SpeedTouch router"
    __metaclass__=WithDeclaredNames
    declared = ['connect', 'uid', 'pwd', 'rtuid', 'rtpwd']
    
    def __init__(self, connect, uid, pwd, rtuid, rtpwd):
        self.connect = connect
        self.uid = uid
        self.pwd = pwd
        self.rtuid = rtuid
        self.rtpwd = rtpwd
        self.namenotinslots = ''

o = SpeedTouchComm(1,2,3,4,5)

Traceback (most recent call last):
  File "<stdin>", line 28, in ?
  File "<stdin>", line 26, in __init__
  File "<stdin>", line 11, in setattr
__main__.UndeclaredNameError: namenotinslots




More information about the Python-list mailing list