Как проверить поведение, похожее на список [duplicate]

Связанный .lib-файл связан с .dll

У меня была такая же проблема. Скажем, у меня есть проекты MyProject и TestProject. Я эффективно связал файл lib для MyProject с TestProject. Однако этот файл lib был создан, так как была построена DLL для MyProject. Кроме того, я не содержал исходный код для всех методов в MyProject, но только доступ к точкам входа DLL.

Чтобы решить проблему, я построил MyProject как LIB и связал TestProject с этим .lib-файлом (скопируйте вложенный файл .lib в папку TestProject). Затем я смогу снова создать MyProject как DLL. Он компилируется, поскольку lib, с которым связан TestProject, содержит код для всех методов в классах MyProject.

810
задан John Kugelman 12 November 2013 в 03:38
поделиться

16 ответов

Согласно глоссарию Python 2 , итерабельными являются

все типы последовательностей (такие как list, str и tuple), а некоторые типы non-sequence, такие как dict и file, и объекты любых классов, которые вы определяете с помощью метода __iter__() или __getitem__(). Итераторы могут использоваться в цикле for и во многих других местах, где необходима последовательность (zip (), map (), ...). Когда итерируемый объект передается как аргумент встроенной функции iter (), он возвращает итератор для объекта.

Конечно, учитывая общий стиль кодирования для Python на основе тот факт, что «проще попросить прощения, чем разрешение». Общее ожидание заключается в использовании

try:
    for i in object_in_question:
        do_something
except TypeError:
    do_something_for_non_iterable

. Но если вам нужно явно проверить его, вы можете проверить его итерабельность на hasattr(object_in_question, "__iter__") or hasattr(object_in_question, "__getitem__") , Вам нужно проверить оба, потому что str s не имеют метода __iter__ (по крайней мере, не в Python 2, в Python 3 они делают), а потому, что объекты generator не имеют метода __getitem__ .

8
ответ дан Anaphory 25 August 2018 в 13:58
поделиться
try:
  #treat object as iterable
except TypeError, e:
  #object is not actually iterable

Не запускайте проверки, чтобы убедиться, что ваша утка действительно утка, чтобы убедиться, что она итерабельна или нет, обрабатывайте ее так, как если бы она была, и жалуются, если это не так.

18
ответ дан badp 25 August 2018 в 13:58
поделиться
def is_iterable(x):
    try:
        0 in x
    except TypeError:
        return False
    else:
        return True

Это скажет «да» всем типам итерируемых объектов, но в Python 2 он будет указывать «нет» на строки (это то, что я хочу, например, когда рекурсивная функция может принимать строку или контейнер строк. эта ситуация, , прося прощение , может привести к обфуску, и лучше сначала спросить разрешение.)

import numpy

class Yes:
    def __iter__(self):
        yield 1;
        yield 2;
        yield 3;

class No:
    pass

class Nope:
    def __iter__(self):
        return 'nonsense'

assert is_iterable(Yes())
assert is_iterable(range(3))
assert is_iterable((1,2,3))   # tuple
assert is_iterable([1,2,3])   # list
assert is_iterable({1,2,3})   # set
assert is_iterable({1:'one', 2:'two', 3:'three'})   # dictionary
assert is_iterable(numpy.array([1,2,3]))
assert is_iterable(bytearray("not really a string", 'utf-8'))

assert not is_iterable(No())
assert not is_iterable(Nope())
assert not is_iterable("string")
assert not is_iterable(42)
assert not is_iterable(True)
assert not is_iterable(None)

Многие другие стратегии здесь скажут «да» строкам. Используйте их, если это то, что вы хотите.

import collections
import numpy

assert isinstance("string", collections.Iterable)
assert isinstance("string", collections.Sequence)
assert numpy.iterable("string")
assert iter("string")
assert hasattr("string", '__getitem__')

Примечание: is_iterable () будет указывать да на строки типа bytes и bytearray.

  • bytes объекты в Python 3 являются итерабельными True == is_iterable(b"string") == is_iterable("string".encode('utf-8')) В Python 2 такого типа нет.
  • bytearray объекты в Python 2 и 3 являются итерируемыми True == is_iterable(bytearray(b"abc"))

Подход OP hasattr(x, '__iter__') скажет «да» к строкам в Python 3 и нет в Python 2 (независимо от того, '' или b'' или u''). Спасибо @LuisMasuelli за то, что вы заметили, что это также подведет вас на багги __iter__.

2
ответ дан Bob Stein 25 August 2018 в 13:58
поделиться

Вы можете попробовать следующее:

def iterable(a):
    try:
        (x for x in a)
        return True
    except TypeError:
        return False

Если мы сможем сделать генератор, который выполняет итерацию по нему (но никогда не используйте генератор, чтобы он не занимал место), он повторяется. Кажется, что-то вроде «духа». Почему вам нужно определить, является ли переменная итерируемой в первую очередь?

10
ответ дан Chris Lutz 25 August 2018 в 13:58
поделиться

Вместо проверки атрибута __iter__ вы можете проверить атрибут __len__, который реализуется каждым встроенным итерабельным python, включая строки.

>>> hasattr(1, "__len__")
False
>>> hasattr(1.3, "__len__")
False
>>> hasattr("a", "__len__")
True
>>> hasattr([1,2,3], "__len__")
True
>>> hasattr({1,2}, "__len__")
True
>>> hasattr({"a":1}, "__len__")
True
>>> hasattr(("a", 1), "__len__")
True

Объекты без объектов не будут реализовывать это по очевидным причинам. Однако он не улавливает пользовательские итерации, которые не реализуют его, и не генерируют выражения генератора, с которыми iter может справиться. Однако это можно сделать в строке, и добавление простой проверки or выражения для генераторов устранит эту проблему. (Обратите внимание, что запись type(my_generator_expression) == generator вызовет NameError. Вместо этого обратитесь к этому .)

Вы можете использовать GeneratorType из типов:

>>> import types
>>> types.GeneratorType
<class 'generator'>
>>> gen = (i for i in range(10))
>>> isinstance(gen, types.GeneratorType)
True

--- принятый ответ utdemir

(Это делает его полезным для проверки, можете ли вы называть len на объекте.)

0
ответ дан DarthCadeus 25 August 2018 в 13:58
поделиться

Я часто нахожу удобным внутри своих скриптов определение функции iterable. (Теперь включает предложенное Alfe упрощение):

import collections

def iterable(obj):
    return isinstance(obj, collections.Iterable):

, чтобы вы могли проверить, является ли какой-либо объект итерируемым в очень читаемой форме

if iterable(obj):
    # act on iterable
else:
    # not iterable

, как вы это делали бы с callable function

EDIT: если у вас установлен numpy, вы можете просто сделать: из numpy import iterable, что просто что-то вроде

def iterable(obj):
    try: iter(obj)
    except: return False
    return True

Если у вас нет numpy, вы может просто реализовать этот код, или тот, что указан выше.

4
ответ дан fmonegaglia 25 August 2018 в 13:58
поделиться

Duck typing

try:
    iterator = iter(theElement)
except TypeError:
    # not iterable
else:
    # iterable

# for obj in iterator:
#     pass

Проверка типа

Используйте базовые классы Абстрактные базовые классы . Они нуждаются хотя бы в Python 2.6 и работают только для классов нового стиля.

import collections

if isinstance(theElement, collections.Iterable):
    # iterable
else:
    # not iterable

Однако iter() является немного более надежным, как описано в документации :

Проверка isinstance(obj, Iterable) обнаруживает классы, зарегистрированные как Iterable или имеющие метод __iter__(), но не обнаруживает классы, которые повторяются с помощью метода __getitem__(). Единственным надежным способом определить, является ли объект итерируемым, является вызов iter(obj).

493
ответ дан Georg Schölly 25 August 2018 в 13:58
поделиться

Этого недостаточно: объект, возвращенный __iter__, должен реализовать протокол итерации (т. е. метод next). См. Соответствующий раздел в документации .

В Python хорошей практикой является «попытаться увидеть» вместо «проверки».

28
ответ дан Mad Physicist 25 August 2018 в 13:58
поделиться

имеет встроенную функцию:

from pandas.util.testing import isiterable
3
ответ дан MSeifert 25 August 2018 в 13:58
поделиться

Функция isiterable в следующем коде возвращает True, если объект итерируется. если он не является итерабельным возвратом False

def isiterable(object_):
    return hasattr(type(object_), "__iter__")

example

fruits = ("apple", "banana", "peach")
isiterable(fruits) # returns True

num = 345
isiterable(num) # returns False

isiterable(str) # returns False because str type is type class and it's not iterable.

hello = "hello dude !"
isiterable(hello) # returns True because as you know string objects are iterable
1
ответ дан Nomad 25 August 2018 в 13:58
поделиться

Лучшее решение, которое я нашел до сих пор:

hasattr(obj, '__contains__')

, который в основном проверяет, реализует ли объект оператор in.

Преимущества (ни одно из других решений не имеет всех трех):

  • это выражение (работает как лямбда, в отличие от try ... except variant)
  • это (должно быть) реализовано всеми итерами, включая строки (в отличие от __iter__)
  • работает на любом Python> = 2.5

Примечания:

  • философия Python «просить прощения, а не разрешения» не работает, когда, например, в списке у вас есть как итерации, так и не-итерации, и вам нужно обрабатывать каждый элемент по-разному в соответствии с его типом (обработка итераций в try и non-iterables за исключением будет работать , но будет выглядеть как butt- уродливые и вводящие в заблуждение)
  • решения этой проблемы, которые пытаются фактически перебирать объект (например, [x для x в obj]), чтобы проверить, может ли он быть итерабельным, могут вызвать значительные штрафы за производительность для больших итераций (особенно если вы просто понадобятся первые несколько элементов итерации, например), и их следует избегать
16
ответ дан not not totallyhuman 25 August 2018 в 13:58
поделиться

Самый простой способ, уважающий задание Python duck typing , состоит в том, чтобы поймать ошибку (Python отлично знает, чего он ожидает от объекта, чтобы стать итератором):

class A(object):
    def __getitem__(self, item):
        return something

class B(object):
    def __iter__(self):
        # Return a compliant iterator. Just an example
        return iter([])

class C(object):
    def __iter__(self):
        # Return crap
        return 1

class D(object): pass

def iterable(obj):
    try:
        iter(obj)
        return True
    except:
        return False

assert iterable(A())
assert iterable(B())
assert iterable(C())
assert not iterable(D())

Примечания:

  1. Не имеет значения, является ли объект неистребимым, или была выполнена ошибка __iter__, если тип исключения один и тот же: в любом случае вы не сможете для итерации объекта.
  2. Думаю, я понимаю вашу озабоченность: как callable существует как проверка, могу ли я также полагаться на утиную печать, чтобы поднять AttributeError, если __call__ не определен для мой объект, но это не так для повторной проверки? Я не знаю ответа, но вы можете либо реализовать функцию I (и других пользователей), либо просто уловить исключение в вашем коде (ваша реализация в этой части будет похожа на написанную мной функцию), просто убедитесь, что вы изолируете создание итератора из остальной части кода, чтобы вы могли зафиксировать исключение и отличить его от другого TypeError.
14
ответ дан Peter Mortensen 25 August 2018 в 13:58
поделиться

Помимо обычной попытки и, кроме того, вы можете запустить справку.

temp= [1,2,3,4]
help(temp)

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

Примечание: Это было бы сделано вручную.

-2
ответ дан prudhvi Indana 25 August 2018 в 13:58
поделиться

Начиная с Python 3.5 вы можете использовать модуль typing из стандартной библиотеки для связанных типов вещей:

from typing import Iterable

...

if isinstance(my_item, Iterable):
    print(True)
3
ответ дан Rotareti 25 August 2018 в 13:58
поделиться

Я всегда избегал вопроса о том, почему у python есть callable(obj) -> bool, но не iterable(obj) -> bool ... конечно, это легче сделать hasattr(obj,'__call__'), даже если оно медленнее.

Так как почти каждый ответ рекомендует использовать try / except TypeError, где тестирование для исключений обычно считается плохой практикой среди любого языка, вот реализация iterable(obj) -> bool, которую я больше любил и часто использовал:

Для python 2, я использую лямбду только для этого дополнительного повышения производительности ... (в python 3 не имеет значения, что вы используете для определения функции, def имеет примерно ту же скорость, что и lambda)

iterable = lambda obj: hasattr(obj,'__iter__') or hasattr(obj,'__getitem__')

Обратите внимание, что эта функция выполняется быстрее для объектов с __iter__, поскольку она не проверяет значение для __getitem__.

Большинство итерируемых объектов должны полагаться на __iter__ объекты case возвращаются к __getitem__, хотя требуется, чтобы объект был итерируемым. (и поскольку он является стандартным, он также влияет на объекты C)

0
ответ дан Tcll 25 August 2018 в 13:58
поделиться
58
ответ дан timgeb 25 August 2018 в 13:58
поделиться
Другие вопросы по тегам:

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