Связанный .lib-файл связан с .dll
У меня была такая же проблема. Скажем, у меня есть проекты MyProject и TestProject. Я эффективно связал файл lib для MyProject с TestProject. Однако этот файл lib был создан, так как была построена DLL для MyProject. Кроме того, я не содержал исходный код для всех методов в MyProject, но только доступ к точкам входа DLL.
Чтобы решить проблему, я построил MyProject как LIB и связал TestProject с этим .lib-файлом (скопируйте вложенный файл .lib в папку TestProject). Затем я смогу снова создать MyProject как DLL. Он компилируется, поскольку lib, с которым связан TestProject, содержит код для всех методов в классах MyProject.
Согласно глоссарию Python 2 , итерабельными являются
все типы последовательностей (такие как
blockquote>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__
.
try:
#treat object as iterable
except TypeError, e:
#object is not actually iterable
Не запускайте проверки, чтобы убедиться, что ваша утка действительно утка, чтобы убедиться, что она итерабельна или нет, обрабатывайте ее так, как если бы она была, и жалуются, если это не так.
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__
.
Вы можете попробовать следующее:
def iterable(a):
try:
(x for x in a)
return True
except TypeError:
return False
Если мы сможем сделать генератор, который выполняет итерацию по нему (но никогда не используйте генератор, чтобы он не занимал место), он повторяется. Кажется, что-то вроде «духа». Почему вам нужно определить, является ли переменная итерируемой в первую очередь?
Вместо проверки атрибута __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
blockquote>(Это делает его полезным для проверки, можете ли вы называть
len
на объекте.)
Я часто нахожу удобным внутри своих скриптов определение функции 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, вы может просто реализовать этот код, или тот, что указан выше.
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()
является немного более надежным, как описано в документации :
Проверка
blockquote>isinstance(obj, Iterable)
обнаруживает классы, зарегистрированные как Iterable или имеющие метод__iter__()
, но не обнаруживает классы, которые повторяются с помощью метода__getitem__()
. Единственным надежным способом определить, является ли объект итерируемым, является вызовiter(obj)
.
Этого недостаточно: объект, возвращенный __iter__
, должен реализовать протокол итерации (т. е. метод next
). См. Соответствующий раздел в документации .
В Python хорошей практикой является «попытаться увидеть» вместо «проверки».
pandas имеет встроенную функцию:
from pandas.util.testing import isiterable
Функция 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
Лучшее решение, которое я нашел до сих пор:
hasattr(obj, '__contains__')
, который в основном проверяет, реализует ли объект оператор in
.
Преимущества (ни одно из других решений не имеет всех трех):
__iter__
) Примечания:
Самый простой способ, уважающий задание 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())
Примечания:
__iter__
, если тип исключения один и тот же: в любом случае вы не сможете для итерации объекта. callable
существует как проверка, могу ли я также полагаться на утиную печать, чтобы поднять AttributeError
, если __call__
не определен для мой объект, но это не так для повторной проверки? Я не знаю ответа, но вы можете либо реализовать функцию I (и других пользователей), либо просто уловить исключение в вашем коде (ваша реализация в этой части будет похожа на написанную мной функцию), просто убедитесь, что вы изолируете создание итератора из остальной части кода, чтобы вы могли зафиксировать исключение и отличить его от другого TypeError
. Помимо обычной попытки и, кроме того, вы можете запустить справку.
temp= [1,2,3,4]
help(temp)
help предоставит все методы, которые могут быть запущены на этом объекте (это может быть любой объект и может не быть списком как пример), что в данном случае является темпом.
Примечание: Это было бы сделано вручную.
Начиная с Python 3.5 вы можете использовать модуль typing из стандартной библиотеки для связанных типов вещей:
from typing import Iterable
...
if isinstance(my_item, Iterable):
print(True)
Я всегда избегал вопроса о том, почему у 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)