Pergunta

Acabei de encontrar um problema no subclasse de "tipo" do dicto. Eu substituí o método __iter__ e esperava que ele afetasse outros métodos, como iterkeys, chaves etc. porque eu acreditava que eles chamavam o método __iter__ para obter valores, mas parece que eles são implementados de forma independente e tenho que substituir todos eles.

Isso é um bug ou intenção que eles não usam outros métodos e recuperam valores separadamente?

Não encontrei na documentação Python padrão descrição das chamadas dependência entre métodos de classes padrão. Seria útil para o trabalho de subbluência e para orientação quais métodos são necessários para substituir o comportamento adequado. Existe alguma documentação suplementar sobre os tipos/classes de base do Python?

Foi útil?

Solução

Subclasse Mapping ou MuteableMapping de Módulo de coleções ao invés de dict E você obtém todos esses métodos gratuitamente.

Aqui está um exemplo de um mapeamento mínimo e alguns dos métodos que você recebe de graça:

import collections
class MinimalMapping(collections.Mapping):
    def __init__(self, *items ):
        self.elements = dict(items)
    def __getitem__(self, key):
        return self.elements[key]
    def __len__(self):
        return len(self.elements)
    def __iter__(self):
        return iter(self.elements)

t = MinimalMapping()
print (t.iteritems, t.keys, t.itervalues, t.get)

Para subclasse qualquer um dos contêineres construídos, você sempre deve usar o conjunto de bases apropriado do módulo de coleções.

Outras dicas

Se não for especificado na documentação, é implementação específica. Implementações outras que Cpython podem reutilizar o iter método para implementar iterkeys e outros. Eu não consideraria isso um bug, mas simplesmente um pouco de liberdade para os implementadores.

Suspeito que exista um fator de desempenho na implementação dos métodos de forma independente, especialmente porque os dicionários são tão amplamente utilizados no Python.

Então, basicamente, você deve implementá -los.

Você sabe o ditado: "Você sabe o que acontece quando assume". :-)

Eles não documentam oficialmente essas coisas porque podem decidir mudá -las no futuro. Qualquer documentação não oficial que você possa encontrar simplesmente documentaria o comportamento atual de uma implementação do Python, e confiar nela resultaria em seu código ser muito, muito frágil.

Quando há documentação oficial de métodos especiais, ele tende a descrever o comportamento do intérprete em relação às suas próprias classes, como usar __len__() quando __nonzero__() não é implementado, ou apenas precisando __lt()__ para classificar.

Como o Python usa digitação de pato, você geralmente não precisa herdar de uma classe embutida para fazer sua própria classe agir como uma. Então você pode reconsiderar se subclassifica dict é realmente o que você quer fazer. Você pode escolher uma classe diferente, como algo do collections módulo, ou para encapsular em vez de herdar. (O UserString A classe usa encapsulamento.) Ou apenas comece do zero.

Em vez de subclassem dict, em vez disso, você pode apenas criar a sua própria classe que tem exatamente As propriedades que você deseja sem muitos problemas. Aqui está um blog Publique com um exemplo de como fazer isso. o __str__() O método não é o melhor, mas isso é facilmente corrigido, o restante fornece a funcionalidade que você procura.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top