views:

82

answers:

1
class a(object):
    w='www'
    def __init__(self):
        for i in self.keys():
            print i
    def __iter__(self):
            for k in self.keys():
                yield k

a() # why is there an error here?

Thanks.


Edit: The following class also doesn't extend any class; why it can use keys?

class DictMixin:
    # Mixin defining all dictionary methods for classes that already have
    # a minimum dictionary interface including getitem, setitem, delitem,
    # and keys. Without knowledge of the subclass constructor, the mixin
    # does not define __init__() or copy().  In addition to the four base
    # methods, progressively more efficiency comes with defining
    # __contains__(), __iter__(), and iteritems().

    # second level definitions support higher levels
    def __iter__(self):
        for k in self.keys():
            yield k
    def has_key(self, key):
        try:
            value = self[key]
        except KeyError:
            return False
        return True
    def __contains__(self, key):
        return self.has_key(key)

    # third level takes advantage of second level definitions
    def iteritems(self):
        for k in self:
            yield (k, self[k])
    def iterkeys(self):
        return self.__iter__()

    # fourth level uses definitions from lower levels
    def itervalues(self):
        for _, v in self.iteritems():
            yield v
    def values(self):
        return [v for _, v in self.iteritems()]
    def items(self):
        return list(self.iteritems())
    def clear(self):
        for key in self.keys():
            del self[key]
    def setdefault(self, key, default=None):
        try:
            return self[key]
        except KeyError:
            self[key] = default
        return default
    def pop(self, key, *args):
        if len(args) > 1:
            raise TypeError, "pop expected at most 2 arguments, got "\
                              + repr(1 + len(args))
        try:
            value = self[key]
        except KeyError:
            if args:
                return args[0]
            raise
        del self[key]
        return value
    def popitem(self):
        try:
            k, v = self.iteritems().next()
        except StopIteration:
            raise KeyError, 'container is empty'
        del self[k]
        return (k, v)
    def update(self, other=None, **kwargs):
        # Make progressively weaker assumptions about "other"
        if other is None:
            pass
        elif hasattr(other, 'iteritems'):  # iteritems saves memory and lookups
            for k, v in other.iteritems():
                self[k] = v
        elif hasattr(other, 'keys'):
            for k in other.keys():
                self[k] = other[k]
        else:
            for k, v in other:
                self[k] = v
        if kwargs:
            self.update(kwargs)
    def get(self, key, default=None):
        try:
            return self[key]
        except KeyError:
            return default
    def __repr__(self):
        return repr(dict(self.iteritems()))
    def __cmp__(self, other):
        if other is None:
            return 1
        if isinstance(other, DictMixin):
            other = dict(other.iteritems())
        return cmp(dict(self.iteritems()), other)
    def __len__(self):
        return len(self.keys())
+2  A: 

Why would you expect it to have keys? You didn't define such a method in your class. Did you intend to inherit from a dictionary?

To do that declare class a(dict)

Or maybe you meant a.__dict__.keys()?

As for the large snippet you've posted in the update, read the comment above the class again:

 # Mixin defining all dictionary methods for classes that already have
 # a minimum dictionary interface including getitem, setitem, delitem,
 # and keys

Note that "already have ... keys" part.

The DictMixin class comes from the UserDict module, which says:

class UserDict.DictMixin Mixin defining all dictionary methods for classes that already have a minimum dictionary interface including getitem(), setitem(), delitem(), and keys().

This mixin should be used as a superclass. Adding each of the above methods adds progressively more functionality. For instance, defining all but delitem() will preclude only pop() and popitem() from the full interface.

In addition to the four base methods, progressively more efficiency comes with defining contains(), iter(), and iteritems().

Since the mixin has no knowledge of the subclass constructor, it does not define init() or copy().

Starting with Python version 2.6, it is recommended to use collections.MutableMapping instead of DictMixin.

Note the recommendation in the last part - use collections.MutableMapping instead.

To iterate over attributes of an object:

class A(object):
    def __init__(self):
        self.myinstatt1 = 'one'
        self.myinstatt2 = 'two'
    def mymethod(self):
        pass

a = A()
for attr, value in a.__dict__.iteritems():
    print attr, value
Eli Bendersky
thanks,@Eli Bendersky,and how can i use this class.
zjm1126
Two seconds work with Google found http://blog.ianbicking.org/2007/08/17/dictmixin/, http://docs.python.org/library/userdict.html, and http://snipplr.com/view/6546/creating-dictionarylike-objects-in-python-using-dictmixin/, all of which explain how to use DictMixin - and that was knowing no more than the name. I'm sure baidu could have found those sites for you just as easily.
James Polley