Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > readonly class attribute ?

Reply
Thread Tools

readonly class attribute ?

 
 
bruno modulix
Guest
Posts: n/a
 
      03-15-2005
Hi

How can I make a *class* attribute read-only ?

The answer must be pretty obvious but I just can't find it (it's late
and I've spent all day on metaclasses, descriptors and the like, which,
as fun as it is, may have side-effects on intellectual abilities...)

*The context:*

# library code
class AbstractBaseClass(object):
# snip some stuff here,
# a part of it depending on the derived classes
# defining class attribute class_private_attrib

# client code
class SubClass(AbstractBaseClass):
class_private_attrib = "my private attrib"
# snip


*What I'm looking for: (if possible)*

>>SubClass.class_private_attrib

"my private attrib"
>>SubClass.class_private_attrib = "toto"

AttributeError : SubClass.class_private_attrib is read only
>>s = SubClass()
>>s.class_private_attribute = "toto"

AttributeError : SubClass.class_private_attrib is read only

*What I've tried: (simplified as possible)*

class ReadOnlyDescriptor(object):
def __init__(self, name, initval=None):
self._val = initval
self._name = name

def __get__(self, obj, objtype):
print 'Retrieving', self._name
return self._val

def __set__(self, obj, val):
raise AttributeError, \
"%s.%s is ReadOnly" % (obj.__class.__.__name__, self._name)

class SubClass(object):
class_private_attrib = ReadOnlyDescriptor("class_private_attrib",
"my private attrib")
# snip

*What i get:*
>>SubClass.class_private_attrib

Retrieving class_private_attrib
"my private attrib"
>>SubClass.class_private_attrib = "toto"
>>SubClass.class_private_attrib

"toto"
>>SubClass.__dict__['class_private_attrib']

"toto"
>> s = SubClass()
>> s.class_private_attrib

"toto" # of course

*What I understand:*
Ok, I've re-read the manual, noticed that data descriptors __set__()
method was only called when an instance attribute is set (which is
obvious from the prototypes of the methods). My solution is plain wrong
and I should have guess without ever trying. duh


Now please have mercy, you Noble Pythoneers : what's the trick to
prevent client code to accidentally mess with the class's dict ? (most
client code - apart from subclass definitions - shouldn't even bother
about the existence of this attribute, it's there for the library
internal usage)

NB : in the real code I'm also messing with the AbstractBaseClass's
meta_class for other stuff (so it's not a problem if the solution
involves metaclasses), but I've tested with the simplified example
above, which exhibits the same problem.

TIA
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in '(E-Mail Removed)'.split('@')])"
 
Reply With Quote
 
 
 
 
Simon Percivall
Guest
Posts: n/a
 
      03-15-2005
Start the attribute name with "_" and don't document it. If clients
mess with it, they're to blame.

 
Reply With Quote
 
 
 
 
Bengt Richter
Guest
Posts: n/a
 
      03-15-2005
On Tue, 15 Mar 2005 20:21:19 +0100, bruno modulix <(E-Mail Removed)> wrote:

>Hi
>
>How can I make a *class* attribute read-only ?
>
>The answer must be pretty obvious but I just can't find it (it's late
>and I've spent all day on metaclasses, descriptors and the like, which,
>as fun as it is, may have side-effects on intellectual abilities...)
>
>*The context:*
>
># library code
>class AbstractBaseClass(object):
> # snip some stuff here,
> # a part of it depending on the derived classes
> # defining class attribute class_private_attrib
>
># client code
>class SubClass(AbstractBaseClass):
> class_private_attrib = "my private attrib"
> # snip
>
>
>*What I'm looking for: (if possible)*
>
> >>SubClass.class_private_attrib

>"my private attrib"
> >>SubClass.class_private_attrib = "toto"

>AttributeError : SubClass.class_private_attrib is read only
> >>s = SubClass()
> >>s.class_private_attribute = "toto"

>AttributeError : SubClass.class_private_attrib is read only
>
>*What I've tried: (simplified as possible)*
>
>class ReadOnlyDescriptor(object):
> def __init__(self, name, initval=None):
> self._val = initval
> self._name = name
>
> def __get__(self, obj, objtype):
> print 'Retrieving', self._name
> return self._val
>
> def __set__(self, obj, val):
> raise AttributeError, \
> "%s.%s is ReadOnly" % (obj.__class.__.__name__, self._name)
>
>class SubClass(object):
> class_private_attrib = ReadOnlyDescriptor("class_private_attrib",
> "my private attrib")
> # snip
>
>*What i get:*
> >>SubClass.class_private_attrib

>Retrieving class_private_attrib
>"my private attrib"
> >>SubClass.class_private_attrib = "toto"
> >>SubClass.class_private_attrib

>"toto"
> >>SubClass.__dict__['class_private_attrib']

>"toto"
> >> s = SubClass()
> >> s.class_private_attrib

>"toto" # of course
>
>*What I understand:*
>Ok, I've re-read the manual, noticed that data descriptors __set__()
>method was only called when an instance attribute is set (which is
>obvious from the prototypes of the methods). My solution is plain wrong
>and I should have guess without ever trying. duh
>
>
>Now please have mercy, you Noble Pythoneers : what's the trick to
>prevent client code to accidentally mess with the class's dict ? (most
>client code - apart from subclass definitions - shouldn't even bother
>about the existence of this attribute, it's there for the library
>internal usage)
>
>NB : in the real code I'm also messing with the AbstractBaseClass's
>meta_class for other stuff (so it's not a problem if the solution
>involves metaclasses), but I've tested with the simplified example
>above, which exhibits the same problem.
>

Does this help, or did I misunderstand?

>>> class Base(object):

... class __metaclass__(type):
... def __setattr__(cls, name, value):
... raise AttributeError, 'setting %r to %r not allowed' %(name, value)
...
>>> class Sub(Base):

... def m(self): print 'method m called'
... x = 123
...
>>> obj = Sub()


Instance attributes work normally:
>>> obj.x

123
>>> obj.x = 456
>>> obj.x

456
>>> del obj.x


If not shadowed, the class var is found
>>> Sub.x

123

But it is read-only:
>>> Sub.x = 456

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 4, in __setattr__
AttributeError: setting 'x' to 456 not allowed

>>> Base.x = 456

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 4, in __setattr__
AttributeError: setting 'x' to 456 not allowed
>>> Sub.anything = 'something'

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 4, in __setattr__
AttributeError: setting 'anything' to 'something' not allowed

Regards,
Bengt Richter
 
Reply With Quote
 
Bruno Desthuilliers
Guest
Posts: n/a
 
      03-15-2005
Simon Percivall a écrit :
> Start the attribute name with "_" and don't document it. If clients
> mess with it, they're to blame.


The problem is that client code must *define* this attribute when
subclassing BaseClass - and that's (well, in most case that should be)
the only place where they have to deal with it (unless they want to do
mumbo-jumbo thangs, in which case that's not my problem anymore !-).

What I want is to prevent client code to accidentally mess with it, and
have strange bugs that they may have hard time to fix. At the same time,
I want to have the cleanest syntax for the subclass declaration. In
fact, in most cases, the client code should not have much more to do
than defining a handfull of class attributes to end up with a
taylor-made fully functional subclass.

Bruno
 
Reply With Quote
 
Bruno Desthuilliers
Guest
Posts: n/a
 
      03-15-2005
Bengt Richter a écrit :
> On Tue, 15 Mar 2005 20:21:19 +0100, bruno modulix <(E-Mail Removed)> wrote:
>
>
>>Hi
>>
>>How can I make a *class* attribute read-only ?
>>

(snip)
>
> Does this help, or did I misunderstand?
>
> >>> class Base(object):

> ... class __metaclass__(type):
> ... def __setattr__(cls, name, value):
> ... raise AttributeError, 'setting %r to %r not allowed' %(name, value)


Pretty obvious, indeed !

Bengt, if we meet one day, remind me to pay you a couple of your
favorite drink !-)
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Is it safe to reset table.column.Readonly attribute for updates? Bogdan ASP .Net 0 04-17-2008 02:04 PM
How to generate readonly attribute correctly? Hamed ASP .Net 3 07-09-2006 01:23 PM
readOnly attribute doesn't work for drop down list? Matt HTML 2 06-29-2004 12:22 AM
problem to disable or enable READONLY attribute Matt HTML 1 06-22-2004 01:49 AM
ASP.NET Readonly panel function with readonly checkbox, readonly radiobutton Jonathan Hyatt ASP .Net Web Controls 1 06-08-2004 07:42 PM



Advertisments