Python 中 abc.Sequence 的等价物 2
The equivalents of abc.Sequence in Python 2
我需要将一些 Python 3 代码转换为 Python 2 代码
from collections.abc import Sequence
def to_tensor(X, device):
.....
if isinstance(X, (list, tuple)):
return [to_tensor_(x) for x in X]
if isinstance(X,Sequence):<-------equals to if isinstance(X,(str,bytes))?
X = torch.tensor(np.array(X))
return X.to(device)
如上所示,我想知道是否:
isinstance(X,Sequence)
等于
isinstance(X,(str,bytes))
和the documentation
对我来说没有任何意义。
简答:不,这不等同。
最长的答案:
首先,Python2 没有 "bytes" 类型 - Python3 bytes
是 Python2 str
和 Python3 str
是 Python2 unicode
,所以正确的问题是:isinstance(X,Sequence)
是否等同于 isinstance(X, (unicode, str))
.
那么,答案是还是没有。 Py3 str
和 bytes
确实是 abc.Sequence
的实例, 但是 实现 abc.Sequence
的 class 的任何实例也是如此,因此您可以拥有 Sequence
而不是 str
或 bytes
的对象((Django orm 的 Queryset
class 将是一个完美的候选对象)。
and this doc: https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence make not no sense to me
如果您遵循本文档中的 link,"sequence" 的 you get a verbal definition 是:
An iterable which supports efficient element access using integer
indices via the getitem() special method and defines a len()
method that returns the length of the sequence
(..)
Note that dict also supports getitem() and len(), but is considered a mapping rather than a sequence
根据这个定义,要测试一个对象是否是一个序列,你必须测试它是否可迭代,有一个 __getitem__
和一个 __len_
方法并且不是 dict
.这不会是 py3 代码的 exact 等价物,但它是你可以获得的更接近的(至少没有更多上下文,请参见下面):
def is_sequence(obj):
if isinstance(obj, dict):
return False
if not (
hasattr(obj, "__getitem__")
and hasattr(obj, "__len__")
):
return False
# we might have false postive here
# with dict-likes not inheriting from
# `dict`, so we also weed out objects
# having a `keys()` methods which
# are most likely dict-likes
if hasattr(obj, "keys"):
return False
return True
现在,您的问题的真正答案可能有点不同:"sequence" 有(或多或少)正式定义,还有您要移植的代码的上下文调用和作者的意图。
作者可能假设他的函数只会传递列表、元组、字符串或字节,在这种情况下,测试意图确实被误导了(我什至会说损坏了)和未记录的尝试检查字符串和字节。
或者作者可能假设他的函数永远不会传递字符串或字节,但后来我不明白为什么他会以不同于其他序列的方式对待列表和元组。
长话短说:您将不得不研究上下文,或者最终要求作者进行澄清 - 当然,如果可能的话。
我需要将一些 Python 3 代码转换为 Python 2 代码
from collections.abc import Sequence
def to_tensor(X, device):
.....
if isinstance(X, (list, tuple)):
return [to_tensor_(x) for x in X]
if isinstance(X,Sequence):<-------equals to if isinstance(X,(str,bytes))?
X = torch.tensor(np.array(X))
return X.to(device)
如上所示,我想知道是否:
isinstance(X,Sequence)
等于
isinstance(X,(str,bytes))
和the documentation 对我来说没有任何意义。
简答:不,这不等同。
最长的答案:
首先,Python2 没有 "bytes" 类型 - Python3 bytes
是 Python2 str
和 Python3 str
是 Python2 unicode
,所以正确的问题是:isinstance(X,Sequence)
是否等同于 isinstance(X, (unicode, str))
.
那么,答案是还是没有。 Py3 str
和 bytes
确实是 abc.Sequence
的实例, 但是 实现 abc.Sequence
的 class 的任何实例也是如此,因此您可以拥有 Sequence
而不是 str
或 bytes
的对象((Django orm 的 Queryset
class 将是一个完美的候选对象)。
and this doc: https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence make not no sense to me
如果您遵循本文档中的 link,"sequence" 的 you get a verbal definition 是:
An iterable which supports efficient element access using integer indices via the getitem() special method and defines a len() method that returns the length of the sequence (..) Note that dict also supports getitem() and len(), but is considered a mapping rather than a sequence
根据这个定义,要测试一个对象是否是一个序列,你必须测试它是否可迭代,有一个 __getitem__
和一个 __len_
方法并且不是 dict
.这不会是 py3 代码的 exact 等价物,但它是你可以获得的更接近的(至少没有更多上下文,请参见下面):
def is_sequence(obj):
if isinstance(obj, dict):
return False
if not (
hasattr(obj, "__getitem__")
and hasattr(obj, "__len__")
):
return False
# we might have false postive here
# with dict-likes not inheriting from
# `dict`, so we also weed out objects
# having a `keys()` methods which
# are most likely dict-likes
if hasattr(obj, "keys"):
return False
return True
现在,您的问题的真正答案可能有点不同:"sequence" 有(或多或少)正式定义,还有您要移植的代码的上下文调用和作者的意图。
作者可能假设他的函数只会传递列表、元组、字符串或字节,在这种情况下,测试意图确实被误导了(我什至会说损坏了)和未记录的尝试检查字符串和字节。
或者作者可能假设他的函数永远不会传递字符串或字节,但后来我不明白为什么他会以不同于其他序列的方式对待列表和元组。
长话短说:您将不得不研究上下文,或者最终要求作者进行澄清 - 当然,如果可能的话。