len (объект) или hasattr (объект, __iter__)? - PullRequest
0 голосов
/ 19 ноября 2009

(следующее относится к python3 (если это имеет значение).)

Это код, который я написал (упрощенно):

class MyClass:

    def __init__(self):
        self.__some_var = []

    @property
    def some_var(self):
        return self.__some__var

    @some_var.setter
    def some_var(self, new_value):
        if hasattr(new_value, '__iter__'):
            self.__some_var = new_value
        else:
            self.__some_var.append(new_value)

Я хочу заменить при установке, если они имеют несколько «значений» (т. Е. Если new_value является итерируемым из, в моем случае, не повторяемых объектов), и добавить, если их является только одним «значением». Я обеспокоен производительностью hasattr, поэтому мне интересно, не стоит ли мне использовать этот метод установки:

    @some_var.setter
    def some_var(self, *args):
        if len(args) > 1:
            self.__some_var = args
        else:
            self.__some_var.append(args)

Спасибо за внимание!

Ответы [ 3 ]

4 голосов
/ 19 ноября 2009

Нет никакой "стоимости производительности" hasattr, которая имеет значение. Это достаточно быстро, чтобы вам было трудно его измерить.

Пожалуйста, не используйте __ (двойное подчеркивание) для своих собственных атрибутов. Это смущает остальных из нас.

Обычно для такого рода вещей лучше использовать членство collections Abstract Base Class.

if isinstance( arg, collections.Sequence ):
    self._some_var = list(arg)
else:
    self._some_var.append( arg )

Это дает вам кое-что, что, вероятно, будет работать лучше, потому что оно выражает семантику немного яснее.

2 голосов
/ 19 ноября 2009

Альтернативой может быть утка:

Здесь я предполагаю, что вы хотите оценить (= составить список) из итерируемого, поскольку это может быть итератор, который вам нужно немедленно развернуть для сохранения.

@some_var.setter
def some_var(self, new_value):
    try:
        self.__some_var = list(new_value)
    except TypeError:
        self.__some_var.append(new_value)

Здесь мы ожидаем, что list() повысит ValueError, если new_value не повторяется. В ответ на ваш комментарий к ответу S.Lott, я не думаю, что использование hasattr - это действительно стиль утки.

0 голосов
/ 19 ноября 2009

С точки зрения эффективности:

  • hasattr () будет иметь наихудший случай O (1) (константа).
  • append () также является наихудшим случаем O (1) (константа).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...