可听写类的Python习语?

可听写类的Python习语?,python,abc,Python,Abc,我想这样做: class Dictable: def dict(self): raise NotImplementedError class Foo(Dictable): def dict(self): return {'bar1': self.bar1, 'bar2': self.bar2} 有没有更像蟒蛇的方法?例如,是否可以重载内置转换dict(…)?请注意,我不一定要返回Foo的所有成员变量,而是让每个类决定返回什么 谢谢。你当然可以重

我想这样做:

class Dictable:
    def dict(self):
        raise NotImplementedError

class Foo(Dictable):
    def dict(self):
        return {'bar1': self.bar1, 'bar2': self.bar2}
有没有更像蟒蛇的方法?例如,是否可以重载内置转换
dict(…)
?请注意,我不一定要返回
Foo
的所有成员变量,而是让每个类决定返回什么


谢谢。

你当然可以重载dict(),但你几乎永远都不想!标准库的太多方面依赖于dict的可用性,您将破坏它的大部分功能。不过,您可能会这样做:

class Dictable:
   def dict(self):
     return self.__dict__

蟒蛇的方式取决于你想做什么。如果您的对象本身不应该被视为映射,那么
dict
方法是非常好的,但是您不应该“重载”
dict
来处理dictable。您是否需要基类取决于您是否要执行
isinstance(x,Dictable)
;请注意,
hasattr(x,“dict”)
的作用几乎相同

如果类在概念上是键到值的映射,那么实现协议似乎是合适的。也就是说,你要实施

  • \uuuu获取项目\uuuuu
  • \uuuuu iter\uuuuuu
  • \uuuu len\uuuu
并从
collections.Mapping
继承以获取其他方法。然后您可以免费获得dict(Foo())。例如:

class Foo(Mapping):
    def __getitem__(self, key):
        if key not in ("bar1", "bar2"):
            raise KeyError("{} not found".format(repr(key))
        return getattr(self, key)

    def __iter__(self):
        yield "bar1"
        yield "bar2"

    def __len__(self):
        return 2
首先,看一看,它描述了Python抽象基类协议(相当于静态语言中的接口)

然后,决定你是想写你自己的ABC还是利用现有的ABC;在这种情况下,可能是你想要的

请注意,尽管
dict
构造函数(即
dict(my_object)
)不可重写,但如果它遇到一个可生成键值对序列的iterable对象,它将从该对象构造一个dict;i、 e.(Python 2;对于Python 3,将
项替换为
iteritems
):


但是,如果您的类的行为与
dict
类似,则不应该这样做,因为这与
映射
实例的预期行为不同,后者是迭代键,而不是键值对。特别是,它会导致..的
。。在
中,你可能会表现得不正确。

这里的大多数答案都是关于让你的课堂表现得像一个听写,而这实际上并不是你所要求的。如果您想表达“我是一个可以转换为dict的类”的想法,我只需定义一组类,并让它们各自实现.dict()。Python喜欢鸭子类型(对象可以做什么)而不是对象是什么。ABC没有增加多少内容。文档也有同样的用途。

您是否考虑过重载getitem或setitem,以便可以说foo['key']?(给定foo是您类的一个实例)@JonClements我的用例是我有一些对象,这些对象都应该能够序列化为JSON对象,并在web服务器应用程序中返回。我将它们转换成
dict
s,因为web框架自动处理
dict->JSON字符串部分。而且它们不能仅仅是
dict
s,因为它们也是SQLAlchemy ORM类。
映射上的
iter
应该生成键,而不是键值对。@larsmans很好,我只是在想这有多不和谐。威尔更正。奇怪的是,我在
映射的文档中找不到这个要求,也在映射的词汇表中找不到…@larsmans,它应该迭代容器的键,因为我们没有用例,所以看不到这方面的需求-但我的答案也基于ABC的-一个dict就可以完成这项工作-如果真的需要属性访问,那么
命名的tuple
作为
键的
部分可能更有用我使用的是
Dictable
for are-SQLAlchemy-ORM类,因此我认为它们除了将键映射到值(以及一些隐藏的数据库内容)之外,没有什么作用。
def __iter__(self):
    return {'bar1': self.bar1, 'bar2': self.bar2}.iteritems()