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 the __private_variables and the getter/setter approach, look
at the list of methods in the __slots__.
I note that all methods in an instance of a slotted class are read-only
irrespective of whether their names are included in __slots__ or not:
Given a = Adder(),
a.tally = 0
gets AttributeError: 'Adder' object attribute 'tally' is read-only
a.notinslots = 1
gets AttributeError: 'Adder' object attribute 'notinslots' is read-only
So is there some magic class-fu going down here, or is this just a
waste of memory space in the instances?
=== example ===
# class with method names in __slots__
class Adder(object):
__slots__ = [
# methods
'__init_',
'get_foo',
'get_value',
'set_foo',
'tally',
# private variables
'__foo',
'__value',
# public variables
'bar',
'zot',
]
def __init__(self, start=0):
self.__value = start
self.__foo = 666
self.bar = None
self.zot = 42
def tally(self, amount):
self.__value += amount
def get_value(self):
return self.__value
def set_foo(self, arg):
self.__foo = arg
def get_foo(self):
return self.__foo
def notinslots(self):
pass
=== end of example === 3 1581
John Machin wrote in news:1167008799.074885.250770@
73g2000cwn.googlegroups.com in comp.lang.python:
Given a = Adder(),
a.tally = 0
gets AttributeError: 'Adder' object attribute 'tally' is read-only
a.notinslots = 1
gets AttributeError: 'Adder' object attribute 'notinslots' is read-only
So is there some magic class-fu going down here, or is this just a
waste of memory space in the instances?
Haven't you, with your 2 examples above, answered your own question ?
Clearly from your example it doesn't make any difference if you add
a class attribute to the slots, one way or another its as if you
hadn't put it in there in the first place.
This will give the same error, which shows its about class attributes
and not just methods:
class Adder(object):
__slots__ = [
'class_name'
]
class_name = 3
a = Adder()
a.class_name = 2
It would seem that the interpreter removes any names it finds as class
attribute names from the list it finds in __slots__ before it creates
the instance.
Of course if my guessing above isn't good enough, we could look at
the documentation: http://docs.python.org/ref/slots.html#l2h-218
__slots__ are implemented at the class level by creating descriptors
(3.4.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.
So its that the __slots__ assignment makes the descriptors and then the
subsiquent method defenitions and class attribute bindings remove them.
Rob.
-- http://www.victim-prime.dsl.pipex.com/
Rob Williscroft wrote:
John Machin wrote in news:1167008799.074885.250770@
73g2000cwn.googlegroups.com in comp.lang.python:
Given a = Adder(),
a.tally = 0
gets AttributeError: 'Adder' object attribute 'tally' is read-only
a.notinslots = 1
gets AttributeError: 'Adder' object attribute 'notinslots' is read-only
So is there some magic class-fu going down here, or is this just a
waste of memory space in the instances?
Haven't you, with your 2 examples above, answered your own question ?
No.
>
Clearly from your example it doesn't make any difference if you add
a class attribute to the slots, one way or another its as if you
hadn't put it in there in the first place.
Clearly? Not so. It takes up memory. A list of 1 million Adder
instances takes up about 68 Mb (Python 2.5 on Windows XP). With the
method names removed from the __slots__, it takes only about 44 Mb.
[For comparison: with no __slots__ at all, it takes about 180 Mb]
>
This will give the same error, which shows its about class attributes
and not just methods:
class Adder(object):
__slots__ = [
'class_name'
]
class_name = 3
a = Adder()
a.class_name = 2
It would seem that the interpreter removes any names it finds as class
attribute names from the list it finds in __slots__ before it creates
the instance.
It doesn't seem so to me. If it did that, the memory usage would not
increase.
>
Of course if my guessing above isn't good enough, we could look at
the documentation:
http://docs.python.org/ref/slots.html#l2h-218
__slots__ are implemented at the class level by creating descriptors
(3.4.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 have read that, before I posted. Asides:
(1) It would be useful if it stated the empirically determined fact
that the result is that the class attribute is thusly made read-only.
(2) The second sentence is not a model of clarity.
In any case I can't see how the paragraph gives any support for your
next statement:
>
So its that the __slots__ assignment makes the descriptors and then the
subsiquent method defenitions and class attribute bindings remove them.
Errrmmm ... if the descriptors are removed, how is it that the
behaviour is read-only?
Cheers,
John
John Machin wrote in
news:11*********************@n51g2000cwc.googlegro ups.com in
comp.lang.python:
Rob Williscroft wrote:
>John Machin wrote in news:1167008799.074885.250770@ 73g2000cwn.googlegroups.com in comp.lang.python:
Given a = Adder(),
a.tally = 0
gets AttributeError: 'Adder' object attribute 'tally' is read-only
a.notinslots = 1
gets AttributeError: 'Adder' object attribute 'notinslots' is
read-only
So is there some magic class-fu going down here, or is this just a
waste of memory space in the instances? Haven't you, with your 2 examples above, answered your own question ?
No.
>> Clearly from your example it doesn't make any difference if you add a class attribute to the slots, one way or another its as if you hadn't put it in there in the first place.
Clearly? Not so. It takes up memory. A list of 1 million Adder
instances takes up about 68 Mb (Python 2.5 on Windows XP). With the
method names removed from the __slots__, it takes only about 44 Mb.
[For comparison: with no __slots__ at all, it takes about 180 Mb]
68 - 44 = 24
24 / 4 = 6
So thats 6 pointers for 5 methods, probably 5 pointers and and 4 bytes
round up to the nearest allocation unit.
So the slots in the instance are staying arround, even though they
are no longer accesable (see below).
[snip]
It would seem that the interpreter removes any names it finds as
>class attribute names from the list it finds in __slots__ before it creates the instance.
It doesn't seem so to me. If it did that, the memory usage would not
increase.
It was a guess, and an incorrect guess, but thats why I quoted the
docs below.
>
>> Of course if my guessing above isn't good enough, we could look at the documentation:
http://docs.python.org/ref/slots.html#l2h-218
__slots__ are implemented at the class level by creating descriptors (3.4.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 have read that, before I posted. Asides:
(1) It would be useful if it stated the empirically determined fact
that the result is that the class attribute is thusly made read-only.
(2) The second sentence is not a model of clarity.
In any case I can't see how the paragraph gives any support for your
next statement:
>> So its that the __slots__ assignment makes the descriptors and then the subsiquent method defenitions and class attribute bindings remove them.
Errrmmm ... if the descriptors are removed, how is it that the
behaviour is read-only?
The descriptors are part of the class object, they are removed
when the class attributes are rebound, further rebinding of
the class attributes will work fine:
Adder.tally = 0
They are not assignable in the instance as the class descriptors
that would have forwarded the assignment to the instances slots have
been replaced.
The memory usage is higher because the slots in the instance are
still there even though the descriptors that would allow them to
be assigned have been removed.
Rob.
-- http://www.victim-prime.dsl.pipex.com/ This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: simon place |
last post by:
Removing __slots__
~~~~~~~~~~~~~~~~~~~
To do this nicely requires the renaming of __dict__ to, say,
__attribs__ , ( since dict is unnecessarily unspecific, this seem like a
small improvement...
|
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...
|
by: flori |
last post by:
i try to greate somthing like this
class ca(object): __slots__ = ("a",)
class cb(ca): __slots__ = ("a","b")
class cc(ca): __slots__ = ("a","c")
class cd(cb,cc): __slots__ = ("a","b","c","d")
...
|
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...
|
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...
|
by: Schüle Daniel |
last post by:
Hello,
consider this code
>>> class A(object):
.... def __init__(self):
.... self.a = 1
.... self.b = 2
....
>>> class B(A):
|
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...
|
by: Licheng Fang |
last post by:
Python is supposed to be readable, but after programming in Python for
a while I find my Python programs can be more obfuscated than their C/C
++ counterparts sometimes. Part of the reason is that...
|
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...
|
by: Rina0 |
last post by:
Cybersecurity engineering is a specialized field that focuses on the design, development, and implementation of systems, processes, and technologies that protect against cyber threats and...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 2 August 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM)
The start time is equivalent to 19:00 (7PM) in Central...
|
by: erikbower65 |
last post by:
Using CodiumAI's pr-agent is simple and powerful. Follow these steps:
1. Install CodiumAI CLI: Ensure Node.js is installed, then run 'npm install -g codiumai' in the terminal.
2. Connect to...
|
by: linyimin |
last post by:
Spring Startup Analyzer generates an interactive Spring application startup report that lets you understand what contributes to the application startup time and helps to optimize it. Support for...
|
by: kcodez |
last post by:
As a H5 game development enthusiast, I recently wrote a very interesting little game - Toy Claw ((http://claw.kjeek.com/))。Here I will summarize and share the development experience here, and hope it...
|
by: Taofi |
last post by:
I try to insert a new record but the error message says the number of query names and destination fields are not the same
This are my field names
ID, Budgeted, Actual, Status and Differences
...
|
by: Rina0 |
last post by:
I am looking for a Python code to find the longest common subsequence of two strings. I found this blog post that describes the length of longest common subsequence problem and provides a solution in...
|
by: DJRhino |
last post by:
Private Sub CboDrawingID_BeforeUpdate(Cancel As Integer)
If = 310029923 Or 310030138 Or 310030152 Or 310030346 Or 310030348 Or _
310030356 Or 310030359 Or 310030362 Or...
|
by: DJRhino |
last post by:
Was curious if anyone else was having this same issue or not....
I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
| |