473,405 Members | 2,176 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

Setdefault bypasses __setitem__

Is this a bug or a feature?

class mydict(dict):
def __setitem__(self, key, val):
print 'foo'
dict.__setitem__(self, key, val)
d=mydict()
d[1]=2 foo d.setdefault(2,3)

3

rg
Oct 13 '05 #1
9 1711
Ron Garret wrote:
Is this a bug or a feature?

class mydict(dict):
def __setitem__(self, key, val):
print 'foo'
dict.__setitem__(self, key, val)

d=mydict()
d[1]=2
foo
d.setdefault(2,3)

Feature. If it wouldn't bypass __setitem__, how exactly would you make a
default-item? Using __setitem__ implies a key. So if setdefault
was implemented as

def setdefault(self, v):
self["SOME_DEFAULT_KEY_NAME"] = v

and later on one writes e.g. a HTML-page with a form input field named
"SOME_DEFAULT_KEY_NAME" that gets stored in a dict - it would overwrite
the default value.

So it has to bypass __setitem__, as otherwise it can't distinguish
between "real" and the default value - the latter one is not allowed to
have a key that is in any imaginable way used by the user.

Diez
Oct 13 '05 #2
Diez B. Roggisch wrote:
Ron Garret wrote:
Is this a bug or a feature?

class mydict(dict):
def __setitem__(self, key, val):
print 'foo'
dict.__setitem__(self, key, val)

>d=mydict()
>d[1]=2


foo
>d.setdefault(2,3)

Feature. If it wouldn't bypass __setitem__, how exactly would you make a
default-item? Using __setitem__ implies a key. So if setdefault
was implemented as

def setdefault(self, v):
self["SOME_DEFAULT_KEY_NAME"] = v

and later on one writes e.g. a HTML-page with a form input field named
"SOME_DEFAULT_KEY_NAME" that gets stored in a dict - it would overwrite
the default value.

So it has to bypass __setitem__, as otherwise it can't distinguish
between "real" and the default value - the latter one is not allowed to
have a key that is in any imaginable way used by the user.


The implementation is certainly a design decision. setdefault() could be
implemented in terms of __set/getitem__() as

def setdefault(self, key, value=None):
try:
return self[key]
except KeyError:
self[key] = value
return self[key]

I guess it's not done for performance reasons.

Peter

Oct 13 '05 #3
> The implementation is certainly a design decision. setdefault() could be
implemented in terms of __set/getitem__() as

def setdefault(self, key, value=None):
try:
return self[key]
except KeyError:
self[key] = value
return self[key]

I guess it's not done for performance reasons.


Nope. What if you changed your default value? Then you'd have to update
the whole dictionary - but without keeping track of the keys you placed
the default value under that isn't possible. Which strikes me as
more-than-marginal overhead - without any advantage (as using
__setitem__ for the default value isn't something I consider being a
missing feature...)

Diez
Oct 13 '05 #4
Diez B. Roggisch wrote:
The implementation is certainly a design decision. setdefault() could be
implemented in terms of __set/getitem__() as

def setdefault(self, key, value=None):
try:
return self[key]
except KeyError:
self[key] = value
return self[key]

I guess it's not done for performance reasons.


Nope. What if you changed your default value? Then you'd have to update
the whole dictionary - but without keeping track of the keys you placed
the default value under that isn't possible. Which strikes me as
more-than-marginal overhead - without any advantage (as using
__setitem__ for the default value isn't something I consider being a
missing feature...)


Are we talking about the same setdefault()?

setdefault(...)
D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D

There is no per-instance default value just on per call:
d = {}
d.setdefault("a", 1) 1 d.setdefault("a", 42)

1

I'm sure there is a misunderstanding in our conversation, I'm just not able
to nail it...

Peter


Oct 13 '05 #5
Peter Otten wrote:
Are we talking about the same setdefault()?

setdefault(...)
D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D


note that it might be spelled "setdefault", but it should be pronounced
"get or set".

</F>

Oct 13 '05 #6
Diez B. Roggisch wrote:
So if setdefault
was implemented as

def setdefault(self, v):
self["SOME_DEFAULT_KEY_NAME"] = v


if setdefault was implemented that way then all current uses of setdefault
would throw an exception.

setdefault takes *three* parameters: self, key, value. Once you include the
key parameter your entire argument implodes.
Oct 13 '05 #7
Are we talking about the same setdefault()?
D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D

There is no per-instance default value just on per call:


Oh. You're right. I was somehow under the impression that setdefault is
per-instance, so that I can avoid

d.get(key, default)

and write

d[key]

instead, for all keys, and get no more KeyErrors. But then you are
right of course.

Regards,

Diez

Oct 13 '05 #8
Duncan Booth wrote:
Diez B. Roggisch wrote:

So if setdefault
was implemented as

def setdefault(self, v):
self["SOME_DEFAULT_KEY_NAME"] = v

if setdefault was implemented that way then all current uses of setdefault
would throw an exception.

setdefault takes *three* parameters: self, key, value. Once you include the
key parameter your entire argument implodes.


Yup. It does implode, leaving me thunderstruck because of my dumbness.

I rarely find things in python strange or named incorrectly, but this is
IMHO such a case - setdefault led me to think that using it would set a
default value to return for _future_ lookups of non-existant keys. That
semantics is known in e.g. ruby or java.

I think a better name would be getdefault, or even get_setdefault - in
oppposition to the get(key, d) form.

But now that this became clear to me... I guess I can live with the name :)

Diez
Oct 14 '05 #9
Diez B. Roggisch wrote:
I rarely find things in python strange or named incorrectly, but this is
IMHO such a case - setdefault led me to think that using it would set a
default value to return for _future_ lookups of non-existant keys. That
semantics is known in e.g. ruby or java.

I think a better name would be getdefault, or even get_setdefault - in
oppposition to the get(key, d) form.

But now that this became clear to me... I guess I can live with the name :)


as long as you pronounce it correctly (see my earlier post).

</F>

Oct 14 '05 #10

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

Similar topics

5
by: Tino Lange | last post by:
Hi! I just realized that <dict>.setdefault *always* executes the second argument - even if it's not necessary, because the requested item in the first argument exists. This is not what I...
7
by: Leo Breebaart | last post by:
Hi all, I have a question about Python and delayed evaluation. Short-circuiting of Boolean expressions implies that in: >>> if a() and b(): any possible side-effects the call to b() might...
0
by: Cole Tuininga | last post by:
Quick question for y'all - is a dict's setdefault call threadsafe? In other words, if I have code like the following: tmp = someObj() result = dictname.setdefault( key, tmp ) is it...
7
by: gyan | last post by:
follwing code gives error: 1 #include<iostream.h> 2 int main() 3 { 4 int a=5,b; 5 switch(a){ 6 case 1: 7 {b=5; 8 break; 9 }
8
by: Almad | last post by:
Hello, I discovered this behaviour in dictionary which I find confusing. In SneakyLang, I've tried to extend dictionary so it visits another class after something is added: class...
3
by: Tor Erik Soenvisen | last post by:
Hi, What do I need to do to make the code below work as expected: class str2(str): def __setitem__(self, i, y): assert type(y) is str assert type(i) is int assert i < len(self)
12
by: jeremito | last post by:
Please excuse me if this is obvious to others, but I can't figure it out. I am subclassing dict, but want to prevent direct changing of some key/value pairs. For this I thought I should override...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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
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
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.