Документированы вызовы иерархии методов Python std? - PullRequest
1 голос
/ 29 октября 2010

только что столкнулся с проблемой при подклассе dict "type".Я переопределил метод __iter__ и ожидал, что он повлияет на другие методы, такие как iterkeys, ключи и т. Д., Поскольку я полагал, что они вызывают метод __iter__ для получения значений, но кажется, что они реализованы независимо, и мне нужно переопределить все из них.Это ошибка или намерение, что они не используют другие методы и извлекают значения отдельно?

Я не нашел в стандартной документации Python описания зависимости вызовов между методами стандартных классов.Это было бы удобно для работы с подклассами и для ориентации, какие методы необходимо переопределить для правильного поведения.Есть ли дополнительная документация о базовых типах / классах Python?

Ответы [ 4 ]

5 голосов
/ 29 октября 2010

Подкласс Mapping или MuteableMapping из модуля коллекций вместо dict, и вы получаете все эти методы бесплатно.

Вот пример минимального отображения инекоторые из методов, которые вы получаете бесплатно:

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)

Чтобы создать подкласс любого из встроенных контейнеров, вы всегда должны использовать соответствующий базовый класс из модуля коллекций.

2 голосов
/ 29 октября 2010

Если не указано в документации, это специфичная для реализации . Реализации, отличные от того, что CPython может повторно использовать метод iter для реализации iterkeys и другие. Я бы не стал считать это ошибкой, а просто немного свободы для разработчиков.

Я подозреваю, что при независимой реализации методов существует фактор производительности, тем более что словари так широко используются в Python.

Так что, в принципе, вы должны их реализовать.

1 голос
/ 29 октября 2010

Вы знаете поговорку: «Вы знаете, что происходит, когда вы предполагаете».:-)

Они официально не документируют этот материал, потому что могут решить изменить его в будущем.Любая неофициальная документация, которую вы можете найти, просто документирует текущее поведение одной реализации Python, и если полагаться на нее, ваш код будет очень и очень хрупким.

Когда есть официальная документация о специальных методах, это имеетопишите поведение интерпретатора по отношению к вашим собственным классам, например, используйте __len__(), когда __nonzero__() не реализован, или вам нужно только __lt()__ для сортировки.

Так как Python использует типизацию по типу утки, обычнона самом деле не нужно наследовать от встроенного класса, чтобы ваш собственный класс действовал как один.Таким образом, вы могли бы пересмотреть, действительно ли подкласс dict действительно то, что вы хотите сделать.Вы можете выбрать другой класс, например что-то из модуля collections, или инкапсулировать, а не наследовать.(Класс UserString использует инкапсуляцию.) Или просто начните с нуля.

0 голосов
/ 29 октября 2010

Вместо того, чтобы создавать подклассы dict, вы могли бы просто создать make и создать свой собственный класс, который имеет точно свойств, которые вы хотите, без особых проблем. Вот пост blog с примером того, как это сделать. Метод __str__() в нем не самый лучший, но его легко исправить, а остальные обеспечивают необходимую вам функциональность.

...