Корректный способ обнаружить параметр последовательности?

Я считаю, что @Matthew Crumley прав. Они функционально , если не структурно, эквивалентны. Если вы используете Firebug для просмотра объектов, созданных с помощью new, вы можете видеть, что они одинаковы. Однако, мое предпочтение было бы следующим. Я предполагаю, что это просто похоже на то, к чему я привык в C # / Java. То есть, определите класс, определите поля, конструктор и методы.

var A = function() {};
A.prototype = {
    _instance_var: 0,

    initialize: function(v) { this._instance_var = v; },

    x: function() {  alert(this._instance_var); }
};

EDIT Не означает, что область действия переменной была закрытой, я просто пытался проиллюстрировать, как я определите мои классы в javascript. Имя переменной было изменено, чтобы отразить это.

18
задан unwind 4 December 2008 в 14:34
поделиться

12 ответов

проблема со всеми вышеупомянутыми путями состоит в том, что ул. считают последовательностью (это повторяемо, имеет getitem, и т.д.), все же, ее обычно рассматривают как единственный объект.

, Например, функция может принять аргумент, который может или быть именем файла или списком имен файлов. Какова большая часть Pythonic путь к функции для обнаружения первого от последнего?

На основе пересмотренного вопроса, это походит на то, что Вы хотите, что-то больше как:

def to_sequence(arg):
    ''' 
    determine whether an arg should be treated as a "unit" or a "sequence"
    if it's a unit, return a 1-tuple with the arg
    '''
    def _multiple(x):  
        return hasattr(x,"__iter__")
    if _multiple(arg):  
        return arg
    else:
        return (arg,)

>>> to_sequence("a string")
('a string',)
>>> to_sequence( (1,2,3) )
(1, 2, 3)
>>> to_sequence( xrange(5) )
xrange(5)

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

При использовании его, удостоверьтесь, что получает вывод этого, может обработать iterables.

5
ответ дан 30 November 2019 в 07:00
поделиться

С 2,6, используйте абстрактные базовые классы .

>>> import collections
>>> isinstance([], collections.Sequence)
True
>>> isinstance(0, collections.Sequence)
False

, Кроме того, ABC может быть настроена для составления исключений, таких как то, чтобы не полагать, что строки последовательности. Здесь пример:

import abc
import collections

class Atomic(object):
    __metaclass__ = abc.ABCMeta
    @classmethod
    def __subclasshook__(cls, other):
        return not issubclass(other, collections.Sequence) or NotImplemented

Atomic.register(basestring)

После регистрации Атомарный класс может использоваться с [1 121] isinstance и issubclass:

assert isinstance("hello", Atomic) == True

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

Примечание, что в [1 123] Python 3 синтаксис для определения измененных метаклассов и basestring абстрактный суперкласс был удален, который требует, чтобы что-то как следующее использовалось вместо этого:

class Atomic(metaclass=abc.ABCMeta):
    @classmethod
    def __subclasshook__(cls, other):
        return not issubclass(other, collections.Sequence) or NotImplemented

Atomic.register(str)

При желании возможно написать код, который является совместим оба и Python 2.6 + и 3.x, но выполнение так требует использования немного более сложной техники, которая динамично создает необходимый абстрактный базовый класс, таким образом, избегая синтаксических ошибок из-за различия в синтаксисе метакласса. Это - по существу то же как, что Benjamin Peterson шесть модуль with_metaclass() делает функция.

class _AtomicBase(object):
    @classmethod
    def __subclasshook__(cls, other):
        return not issubclass(other, collections.Sequence) or NotImplemented

class Atomic(abc.ABCMeta("NewMeta", (_AtomicBase,), {})):
    pass

try:
    unicode = unicode
except NameError:  # 'unicode' is undefined, assume Python >= 3
    Atomic.register(str)  # str includes unicode in Py3, make both Atomic
    Atomic.register(bytes)  # bytes will also be considered Atomic (optional)
else:
    # basestring is the abstract superclass of both str and unicode types
    Atomic.register(basestring)  # make both types of strings Atomic

В версиях прежде 2.6, существуют средства проверки типа в operator модуль.

>>> import operator
>>> operator.isSequenceType([])
True
>>> operator.isSequenceType(0)
False
19
ответ дан 30 November 2019 в 07:00
поделиться

По моему скромному мнению, Python путь должен передать список как *список. Как в:

myfunc(item)
myfunc(*items)
4
ответ дан 30 November 2019 в 07:00
поделиться

Последовательности описаны здесь: https://docs.python.org/2/library/stdtypes.html#sequence-types-str-unicode-list-tuple-bytearray-buffer-xrange

, Таким образом, последовательности не являются тем же как повторяемыми объектами. Я думаю, что последовательность должна реализовать __getitem__, тогда как повторяемые объекты должны реализовать __iter__. Так, например, представляют в виде строки, последовательности и не реализуют __iter__, xrange объекты последовательности и не реализуют __getslice__.

, Но от того, что Вы замеченный хотеть сделать, я не уверен, что Вы хотите последовательности, а скорее повторяемые объекты. Поэтому пойдите для hasattr("__getitem__", X), Вы хотите последовательности, но идете скорее hasattr("__iter__", X), если Вы не хотите строки, например.

4
ответ дан 30 November 2019 в 07:00
поделиться

В случаях как это я предпочитаю просто, всегда берут тип последовательности или всегда берут скаляр. Строки не будут единственными типами, которые вели бы себя плохо в этой установке; скорее любой тип, который имеет совокупное использование и позволяет повторение по его частям, мог бы неправильно себя вести.

3
ответ дан 30 November 2019 в 07:00
поделиться

Самый простой метод должен был бы проверить, можно ли превратить его в итератор. т.е.

try:
    it = iter(X)
    # Iterable
except TypeError:
    # Not iterable

, Если необходимо удостовериться, что это - последовательность прерываемого или произвольного доступа (т.е. не генератор и т.д.), этот подход не будет достаточен как бы то ни было.

, Поскольку другие отметили, строки также повторяемы, поэтому если Вы должны так исключить их (особенно важный при рекурсивном вызове через объекты, поскольку список (проход) дает снова, затем Вы, возможно, должны конкретно исключить их с:

 if not isinstance(X, basestring)
3
ответ дан 30 November 2019 в 07:00
поделиться

Я являюсь новым здесь, таким образом, я не знаю то, что является корректным способом сделать это. Я хочу ответить на свои ответы:

проблема со всеми вышеупомянутыми путями состоит в том, что str считается последовательностью (это повторяемо, имеет __getitem__, и т.д.), все же, это обычно рассматривают как единственный объект.

, Например, функция может принять аргумент, который может или быть именем файла или списком имен файлов. Какова большая часть Pythonic путь к функции для обнаружения первого от последнего?

я должен отправить это как новый вопрос? Отредактировать исходный?

2
ответ дан 30 November 2019 в 07:00
поделиться

Я думаю, что я сделал бы, проверить, имеет ли объект определенные методы, которые указывают, что это - последовательность. Я не уверен, существует ли официальное определение того, что делает последовательность. Лучшее, о котором я могу думать, это должно поддерживать разрезание. Таким образом, Вы могли сказать:

is_sequence = '__getslice__' in dir(X)

Вы могли бы также проверить на особую функциональность, Вы собираетесь быть использованием.

Как пи, на которое указывают в комментарии, одна проблема - то, что строка является последовательностью, но Вы, вероятно, не хотите рассматривать его как один. Вы могли добавить явный тест, что тип не является ул.

1
ответ дан 30 November 2019 в 07:00
поделиться

Если строки являются проблемой, обнаруживают последовательность и отфильтровывают особый случай строк:

def is_iterable(x):
  if type(x) == str:
    return False
  try:
    iter(x)
    return True
  except TypeError:
    return False
1
ответ дан 30 November 2019 в 07:00
поделиться

Пересмотренный ответ:

я не знаю, соответствует ли Ваша идея "последовательности" тому, что руководства Python называют" Тип Последовательности", но в случае, если это делает, необходимо искать __, Содержит __ метод. Это - метод использование Python для реализации проверки "если что-то в объекте":

if hasattr(X, '__contains__'):
    print "X is a sequence"

Мой исходный ответ:

я проверил бы, реализует ли объект, который Вы получили, интерфейс итератора:

if hasattr(X, '__iter__'):
    print "X is a sequence"

Для меня, это - самое близкое соответствие к Вашему определению последовательности, так как это позволило бы Вам делать что-то как:

for each in X:
    print each
1
ответ дан 30 November 2019 в 07:00
поделиться

Вы задаете неправильный вопрос. Вы не пытаетесь обнаружить типы в Python; Вы обнаруживаете поведение.

  1. Запись другая функция, которая обрабатывает единственное значение. (давайте назовем это _use_single_val).
  2. Запись одна функция, которая обрабатывает параметр последовательности. (давайте назовем это _use_sequence).
  3. Запись третья родительская функция, которая называет два выше. (назовите это use_seq_or_val). Окружите каждый вызов обработчиком исключений для ловли недопустимого параметра (т.е. не единственное значение или последовательность).
  4. модульные тесты Записи для передачи корректного & неправильные параметры к родительской функции для проверки это ловит исключения правильно.

    def _use_single_val(v):
        print v + 1  # this will fail if v is not a value type

    def _use_sequence(s):
        print s[0]   # this will fail if s is not indexable

    def use_seq_or_val(item):    
        try:
            _use_single_val(item)
        except TypeError:
            pass

        try:
            _use_sequence(item)
        except TypeError:
            pass

        raise TypeError, "item not a single value or sequence"

РЕДАКТИРОВАНИЕ: Пересмотренный для обработки "последовательности или единственного значения," спрошенный о в вопросе.

0
ответ дан 30 November 2019 в 07:00
поделиться

Вы могли передать свой параметр во встроенном len () функция и проверить, вызывает ли это ошибку. Как другие сказали, строковый тип требует специальной обработки.

Согласно документации функция len может принять последовательность (строка, список, кортеж) или словарь.

Вы могли проверить, что объект является строкой со следующим кодом:

x.__class__ == "".__class__
-1
ответ дан 30 November 2019 в 07:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: