为什么我的类没有'keys'函数?

0 投票
1 回答
4616 浏览
提问于 2025-04-15 17:32
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?

谢谢。


补充说明:下面这个类也没有继承任何类;那它为什么可以使用 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())

1 个回答

3

你为什么会期待它有 keys 呢?你在你的类里并没有定义这样的一个方法。你是想从字典继承吗?

如果是这样的话,你可以这样声明类 a(dict)

或者你可能是想用 a.__dict__.keys()

关于你在更新中发布的大段代码,重新看看类上面的评论:

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

注意“已经有 ... keys”这部分。

DictMixin 类来自 UserDict 模块,它说:

class UserDict.DictMixin Mixin 定义所有字典方法给 已经有最基本字典接口的类, 包括 getitem()、setitem()、delitem() 和 keys()。

这个 mixin 应该作为一个 超类来使用。添加上述每个 方法会逐渐增加功能。例如,定义 除了 delitem() 之外的所有方法 将只排除 pop() 和 popitem() 的完整 接口。

除了这四个基本方法之外, 定义 contains()、 iter() 和 iteritems() 会 逐渐提高效率。

由于 mixin 对子类构造函数没有 了解,它不定义 init() 或 copy()。

从 Python 2.6 开始,建议使用 collections.MutableMapping 而不是 DictMixin。

注意最后一部分的建议 - 使用 collections.MutableMapping 替代。

要遍历一个对象的属性:

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

撰写回答