473,480 Members | 2,333 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

__slots__ and class attributes

I'm running into a something unexpected for a new-style class
that has both a class attribute and __slots__ defined. If the
name of the class attribute also exists in __slots__, Python
throws an AttributeError. Is this by design (if so, why)?

class A( object ):
__slots__ = ( 'value', )
value = 1

def __init__( self, value = None ):
self.value = value or A.value

a = A()
print a.value
Traceback (most recent call last):
File "t1.py", line 8, in ?
a = A()
File "t1.py", line 6, in __init__
self.value = value or A.value
AttributeError: 'A' object attribute 'value' is read-only
Nov 3 '05 #1
2 4960
Ewald R. de Wit wrote:
I'm running into a something unexpected for a new-style class
that has both a class attribute and __slots__ defined. If the
name of the class attribute also exists in __slots__, Python
throws an AttributeError. Is this by design (if so, why)?

class A( object ):
__slots__ = ( 'value', )
value = 1

def __init__( self, value = None ):
self.value = value or A.value

a = A()
print a.value
Traceback (most recent call last):
File "t1.py", line 8, in ?
a = A()
File "t1.py", line 6, in __init__
self.value = value or A.value
AttributeError: 'A' object attribute 'value' is read-only


Check the documentation on __slots__[1]:

__slots__ are implemented at the class level by creating descriptors
(3.3.2) for each variable name. As a result, class attributes cannot be
used to set default values for instance variables defined by __slots__;
otherwise, the class attribute would overwrite the descriptor assignment.

I agree that the error you get is a bit confusing. I think this has to
do with how the descriptor machinery works. When you write something like
a.value
where a is a class instance, Python tries to invoke something like:
type(a).value.__get__(a)
Here's an example of that, working normallly:

py> class A(object):
.... __slots__ = ['value']
.... def __init__(self):
.... self.value = 1
....
py> a = A()
py> type(a).value
<member 'value' of 'A' objects>
py> type(a).value.__get__
<method-wrapper object at 0x0129A1B0>
py> type(a).value.__get__(a)
1

Now when you add a class attribute called 'value', you overwrite the
descriptor. So when Python tries to do the same thing (because your
definition of __slots__ makes it assume that 'value' is a descriptor),
the descriptor machinery raises an AttributeError:

py> class A(object):
.... __slots__ = ['value']
.... value = 1
....
py> a = A()
py> type(a).value
1
py> type(a).value.__get__
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
AttributeError: 'int' object has no attribute '__get__'

This AttributeError must be somehow caught by the __slots__ machinery
and interpreted to mean that you tried to write to a read-only
attribute. The resulting error message is probably not what you want,
but I don't know the source well enough to figure out whether or not a
better error message could be given.
But why do you want a class level attribute with the same name as an
instance level attribute? I would have written your class as:

class A(object):
__slots__ = ['value']
def __init__(self, value=1):
self.value = value

where the default value you put in the class is simply expressed as a
default value to the __init__ parameter.

Steve

[1]http://docs.python.org/ref/slots.html
Nov 3 '05 #2
Steven Bethard wrote:
But why do you want a class level attribute with the same name as an
instance level attribute? I would have written your class as:

class A(object):
__slots__ = ['value']
def __init__(self, value=1):
self.value = value

where the default value you put in the class is simply expressed as a
default value to the __init__ parameter.


Thanks for your explanation. The reason why I was doing it was
to have class-level defaults, so that one can easily adjust how
new instances will be made. I'm doing it now with capitilized
class attribute names to avoid the name clash.

--
-- Ewald
Nov 4 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
1978
by: anabell | last post by:
I have a code like this: sqlString = 'INSERT INTO ' + self.TableName + ' VALUES (' + self.TableFields + ')' self.cursor.execute(sqlString, self.__dict__) This works correctly. However, I'm...
5
2911
by: Jean Brouwers | last post by:
Classes using __slots__ seem to be quite a bit smaller and faster to instantiate than regular Python classes using __dict__. Below are the results for the __slots__ and __dict__ version of a...
3
1627
by: Nick Jacobson | last post by:
The __slots__ attribute of new-style classes can reduce memory usage when there are millions of instantiations of a class. So would a __slots__ attribute for functions/methods have a similar...
7
1651
by: Porky Pig Jr | last post by:
Hello, I"m still learning Python, but going through the Ch 5 OOP of Nutshell book. There is discussion on __slots__, and my understanding from reading this section is that if I have a class...
2
1202
by: Don Taylor | last post by:
Hi: I am puzzled about the following piece of code which attempts to create a class that can be used as record or struct with a limited set of allowed attributes that can be set into an instance...
1
2693
by: pascal.parent | last post by:
Hi, I try to define a (new-style) class who: - have a __slots__ defined to be strict attributes, - return None if the attribute is 'ok' but not set, or raise a 'normal' error if the attribute...
5
4009
by: jm.suresh | last post by:
Hi all, .... __slots__ = .... .... __slots__ = .... .... __slots__ = .... Traceback (most recent call last): File "<stdin>", line 1, in <module>
3
1609
by: John Machin | last post by:
I have stumbled across some class definitions which include all/most method names in a __slots__ "declaration". A cut-down and disguised example appears at the end of this posting. Never mind...
19
4610
by: jsanshef | last post by:
Hi, after a couple of days of script debugging, I kind of found that some assumptions I was doing about the memory complexity of my classes are not true. I decided to do a simple script to...
0
7051
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7054
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7097
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
6993
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5353
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
3003
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
2993
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
567
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
193
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.