473,721 Members | 2,255 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

why does UserDict.DictMi xin use keys instead of __iter__?

Sorry if this is a repost -- it didn't appear for me the first time.
So I was looking at the Language Reference's discussion about emulating
container types[1], and nowhere in it does it mention that .keys() is
part of the container protocol. Because of this, I would assume that to
use UserDict.DictMi xin correctly, a class would only need to define
__getitem__, __setitem__, __delitem__ and __iter__. So why does
UserDict.DictMi xin require keys() to be defined?

py> class D(object, UserDict.DictMi xin):
.... """Simple dict wrapper that implements container protocol"""
.... def __init__(self, dict): self.dict = dict
.... def __len__(self, key): return len(self.dict)
.... def __getitem__(sel f, key): return self.dict[key]
.... def __setitem__(sel f, key, value): self.dict[key] = value
.... def __delitem__(sel f, key): del self.dict[key]
.... def __iter__(self): return iter(self.dict)
.... def __contains__(se lf, key): return key in self.dict
....
py> d = D(dict(a=1, b=2))
py> d.clear()
Traceback (most recent call last):
File "<interacti ve input>", line 1, in ?
File "C:\Program Files\Python\li b\UserDict.py", line 114, in clear
for key in self.keys():
AttributeError: 'D' object has no attribute 'keys'
py> d.keys()
Traceback (most recent call last):
File "<interacti ve input>", line 1, in ?
AttributeError: 'D' object has no attribute 'keys'
I thought about submitting a patch, but I couldn't think of a way that
didn't raise backwards compatibility concerns...
Steve

[1]http://docs.python.org/ref/sequence-types.html
Jul 18 '05 #1
8 2568
Steven Bethard wrote:
Sorry if this is a repost -- it didn't appear for me the first time.
So I was looking at the Language Reference's discussion about emulating
container types[1], and nowhere in it does it mention that .keys() is
part of the container protocol. Because of this, I would assume that to
use UserDict.DictMi xin correctly, a class would only need to define
__getitem__, __setitem__, __delitem__ and __iter__. So why does
UserDict.DictMi xin require keys() to be defined?


Because it's a DictMixin, not a ContainerMixin?

..keys() is definitely part of the standard dictionary interface, and not
something the mixin can derive from the generic container methods.

Cheers,
Nick.

--
Nick Coghlan | nc******@email. com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net
Jul 18 '05 #2

Steven Bethard wrote:
Sorry if this is a repost -- it didn't appear for me the first time.
So I was looking at the Language Reference's discussion about emulating container types[1], and nowhere in it does it mention that .keys() is
part of the container protocol.
I don't see any reference to a "container protocol". What I do see is
(1) """It is also recommended that mappings provide the methods keys(),
...."""
(2) """The UserDict module provides a DictMixin class to help create
those methods from a base set of __getitem__(), __setitem__(),
__delitem__(), and keys(). """
Because of this, I would assume that to
use UserDict.DictMi xin correctly, a class would only need to define
__getitem__, __setitem__, __delitem__ and __iter__.
So I can't see why would you assume that, given that the docs say in
effect "you supply get/set/del + keys as the building blocks, the
DictMixin class will provide the remainder". This message is reinforced
in the docs for UserDict itself.
So why does
UserDict.DictMi xin require keys() to be defined?


Because it was a reasonable, documented, design?

In any case, isn't UserDict past history? Why are you mucking about
with it?

Jul 18 '05 #3
Nick Coghlan wrote:
Steven Bethard wrote:
Sorry if this is a repost -- it didn't appear for me the first time.
So I was looking at the Language Reference's discussion about emulating
container types[1], and nowhere in it does it mention that .keys() is
part of the container protocol. Because of this, I would assume that to
use UserDict.DictMi xin correctly, a class would only need to define
__getitem__, __setitem__, __delitem__ and __iter__. So why does
UserDict.DictMi xin require keys() to be defined?

Because it's a DictMixin, not a ContainerMixin?


"Containers usually are sequences (such as lists or tuples) or mappings
(like dictionaries)".
.keys() is definitely part of the standard dictionary interface, and not
something the mixin can derive from the generic container methods.


Why is that? Isn't keys derivable as:

def keys(self):
return list(self)

if __iter__ is defined?

Steve
Jul 18 '05 #4
John Machin wrote:
Steven Bethard wrote:
So I was looking at the Language Reference's discussion about
emulating container types[1], and nowhere in it does it mention that
.keys() is part of the container protocol.
I don't see any reference to a "container protocol".


Sorry, I extrapolated "container protocol" from this statement:

"Containers usually are sequences (such as lists or tuples) or mappings
(like dictionaries), but can represent other containers as well. The
first set of methods is used either to emulate a sequence or to emulate
a mapping"

and the fact that there is a "sequence protocol" and a "mapping protocol".

But all I was really reading from this statement was that the "first set
of methods" (__len__, __getitem__, __setitem__, __delitem__ and
__iter__) were more integral than the second set of methods (keys(),
values(), ...).

What I do see is
(1) """It is also recommended that mappings provide the methods keys(),
..."""
You skipped the remaining 13 methods in this list:

"It is also recommended that mappings provide the methods keys(),
values(), items(), has_key(), get(), clear(), setdefault(), iterkeys(),
itervalues(), iteritems(), pop(), popitem(), copy(), and update()
behaving similar to those for Python's standard dictionary objects."

This is the "second set of methods" I mentioned above. I don't
understand why the creators of UserDict.DictMi xin decided that keys(),
from the second list, is more important than __iter__, from the first list.

Because of this, I would assume that to
use UserDict.DictMi xin correctly, a class would only need to define
__getitem__ , __setitem__, __delitem__ and __iter__.

So I can't see why would you assume that, given that the docs say in
effect "you supply get/set/del + keys as the building blocks, the
DictMixin class will provide the remainder". This message is reinforced
in the docs for UserDict itself.


Sorry, my intent was not to say that I didn't know from the docs that
UserDict.DictMi xin required keys(). Clearly it's documented. My
question was *why* does it use keys()? Why use keys() when keys() can
be derived from __iter__, and __iter__ IMHO looks to be a more basic
part of the mapping protocol.
In any case, isn't UserDict past history? Why are you mucking about
with it?


UserDict is past history, but DictMixin isn't. As you note, DictMixin
is even mentioned in the section of the Language Reference that we're
discussing:

"The UserDict module provides a DictMixin class to help create those
methods from a base set of __getitem__(), __setitem__(), __delitem__(),
and keys()."
Steve
Jul 18 '05 #5

Steven Bethard wrote:
John Machin wrote:
Steven Bethard wrote:
So I was looking at the Language Reference's discussion about
emulating container types[1], and nowhere in it does it mention that .keys() is part of the container protocol.
I don't see any reference to a "container protocol".


Sorry, I extrapolated "container protocol" from this statement:

"Containers usually are sequences (such as lists or tuples) or

mappings (like dictionaries), but can represent other containers as well. The
first set of methods is used either to emulate a sequence or to emulate a mapping"

and the fact that there is a "sequence protocol" and a "mapping protocol".
But all I was really reading from this statement was that the "first set of methods" (__len__, __getitem__, __setitem__, __delitem__ and
__iter__) were more integral than the second set of methods (keys(),
values(), ...).

What I do see is
(1) """It is also recommended that mappings provide the methods keys(),
..."""
You skipped the remaining 13 methods in this list:

"It is also recommended that mappings provide the methods keys(),
values(), items(), has_key(), get(), clear(), setdefault(),

iterkeys(), itervalues(), iteritems(), pop(), popitem(), copy(), and update()
behaving similar to those for Python's standard dictionary objects."

This is the "second set of methods" I mentioned above. I don't
understand why the creators of UserDict.DictMi xin decided that keys(), from the second list, is more important than __iter__, from the first list.
Because of this, I would assume that to
use UserDict.DictMi xin correctly, a class would only need to define
__getitem__ , __setitem__, __delitem__ and __iter__.

So I can't see why would you assume that, given that the docs say in effect "you supply get/set/del + keys as the building blocks, the
DictMixin class will provide the remainder". This message is reinforced in the docs for UserDict itself.


Sorry, my intent was not to say that I didn't know from the docs that

UserDict.DictMi xin required keys(). Clearly it's documented.
Sorry, the combination of (a) "assume X where not(X) is documented" and
(b) posting of tracebacks that demonstrated behaviour that is both
expected and documented lead to my making an unwarranted assumption :-)
My
question was *why* does it use keys()? Why use keys() when keys() can be derived from __iter__, and __iter__ IMHO looks to be a more basic
part of the mapping protocol.
Now that I understand your question: Hmmm, good question. __iter__
arrived (2.2) before DictMixin (2.3), so primacy is not the reason.
Ease of implementation by the user of DictMixin: probably not, "yield
akey" vs "alist.append(a key)" -- not much in it in Python, different
story in C, but a C extension wouldn't be using DictMixin anyway.
In any case, isn't UserDict past history? Why are you mucking about
with it?


UserDict is past history, but DictMixin isn't.


OK, I'll rephrase: what is your interest in DictMixin?

My interest: I'm into mappings that provide an approximate match
capability, and have a few different data structures that I'd like to
implement as C types in a unified manner. The plot includes a base type
that, similarly to DictMixin, provides all the non-basic methods.

Jul 18 '05 #6
[Steven Bethard]
Sorry, my intent was not to say that I didn't know from the docs that
UserDict.DictMi xin required keys(). Clearly it's documented. My
question was *why* does it use keys()? Why use keys() when keys() can
be derived from __iter__, and __iter__ IMHO looks to be a more basic
part of the mapping protocol.


Viewed from the present, __iter__() may seem more basic. However, it is a
recent innovation. The keys() method, on the other hand, goes back to the
beginning. There were no shortage of mapping-like classes defining keys() but
not __iter__().

Still, if __iter__() is provided, UserDict.DictMi xin will take advantage of it.
The same is also true for __contains__(), and iteritems().
Raymond Hettinger
Jul 18 '05 #7
John Machin wrote:
OK, I'll rephrase: what is your interest in DictMixin?

My interest: I'm into mappings that provide an approximate match
capability, and have a few different data structures that I'd like to
implement as C types in a unified manner. The plot includes a base type
that, similarly to DictMixin, provides all the non-basic methods.


I was recently trying to prototype a simple mapping type that implements
the suggestion "Improved default value logic for Dictionaries" from
http://www.python.org/moin/Python3_2e0Suggestions
You can't just inherit from dict and override dict.__getitem_ _ because
dict.__getitem_ _ isn't always called:

py> class D(dict):
.... def __init__(*args, **kwds):
.... self = args[0]
.... self.function, self.args, self.kwds = None, None, None
.... super(D, self).__init__( *args[1:], **kwds)
.... def setdefault(self , function, *args, **kwds):
.... self.function, self.args, self.kwds = function, args, kwds
.... def __getitem__(sel f, key):
.... if key not in self:
.... super(D, self).__setitem __(
.... key, self.function(* self.args, **self.kwds))
.... return super(D, self).__getitem __(key)
....
py> d = D()
py> d.setdefault(li st)
py> d['c'].append(2)
py> d
{'c': [2]}
py> print d.get('d') # should print []
None

This, of course, is exactly the kind of thing that DictMixin is designed
for. =)

Of course, it's no trouble for me to implement keys(). I was just
wondering why that design decision was made when it seems like __iter__
is more integral to the mapping protocol. And if you want efficient
iteration over your mapping type, you're going to have to define
__iter__ too...

Steve
Jul 18 '05 #8
Steven Bethard wrote:
Nick Coghlan wrote:
.keys() is definitely part of the standard dictionary interface, and
not something the mixin can derive from the generic container methods.

Why is that? Isn't keys derivable as:

def keys(self):
return list(self)

if __iter__ is defined?


As you may have guessed, I completely forgot about __iter__. . .

Cheers,
Nick.

--
Nick Coghlan | nc******@email. com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net
Jul 18 '05 #9

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

Similar topics

6
1342
by: j_mckitrick | last post by:
I've done this before: data = for k in self.cong.tm.li] #li is list, tm is dict instead of: for k in self.cong.tm.li: data.append(self.cong.tm)
0
1240
by: John Lenton | last post by:
I've recently used UserDict's DictMixin class, and I've found the docs are (somewhat) misguiding: it says, amongst other things, that if my class implements __contains__ some efficiency will be gained; however, looking at the source I see that what I should do is implement has_key, as in DictMixin __contains__ is implemented in terms of has_key and not viceversa, and if I only implement __contains__, has_key will still set up a try/except...
21
2066
by: Steven Bethard | last post by:
Can someone point me to the documentation on what's supposed to happen when you use the "for x in X:" syntax when X does not have an __iter__ method? I know that the code: >>> class S: .... def __len__(self): return 42 .... def __getitem__(self, i): return i .... >>> for x in S(): .... print x
8
2738
by: Uwe Mayer | last post by:
Hi, Why is the UserDict module is deprecated after Python 2.2. The application of it I have in mind is, i.e. multiple inheritance from "file" and "dic" - which is not possible. If I used UserDict I would not need to specify all methods UserDict provides alreay, anyway. Ciao Uwe
5
2860
by: Leif K-Brooks | last post by:
When StringIO gets an initial value passed to its constructor, it seems to discard it after the first call to .write(). For instance: >>> from StringIO import StringIO >>> buffer = StringIO('foo') >>> buffer.getvalue() 'foo' >>> buffer.write('bar') >>> buffer.getvalue() 'bar'
13
1941
by: Thomas Heller | last post by:
I'm trying to implement __iter__ on an abstract base class while I don't know whether subclasses support that or not. Hope that makes sense, if not, this code should be clearer: class Base: def __getattr__(self, name): if name == "__iter__" and hasattr(self, "Iterator"): return self.Iterator raise AttributeError, name
7
3137
by: Chris Stiles | last post by:
Hi -- I'm working on something that includes the concept of multiple aliases for a particular object, where a lookup for any of the aliases has to return all the others. The hack way of doing this was to have a dictionary where each entry consisted of a list of all the aliases - with multiple references to the same list from the various dictionary entries corresponding to each alias. Is there an easier and cleaner way of doing this ? ...
1
1561
by: Petr Prikryl | last post by:
I did observe the problem when using the -U option on Windows 2000. Seems like some infinite recursion in cp1250.py -- see below. I did not try it with earlier versions of Python. Can this be reproduced on your computer? Thanks for your time and experience, pepr
10
2303
by: mrquantum | last post by:
Hello! Just for curiosity i'd like to know why strings don't support the iteration protocoll!? Is there some deeper reason for this? False In Python 2.5 it's actually simple to obtain one: 'S'
0
8858
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9230
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9148
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9085
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8026
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
4499
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 last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4762
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
2596
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2146
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 can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.