这是我通常所做的,以确定输入是一个列表/元组-而不是一个str。因为很多次我偶然发现错误,其中一个函数错误地传递了一个str对象,而目标函数在lst中执行x,假设lst实际上是一个列表或元组。
assert isinstance(lst, (list, tuple))
我的问题是:有没有更好的方法来实现这个目标?
这是我通常所做的,以确定输入是一个列表/元组-而不是一个str。因为很多次我偶然发现错误,其中一个函数错误地传递了一个str对象,而目标函数在lst中执行x,假设lst实际上是一个列表或元组。
assert isinstance(lst, (list, tuple))
我的问题是:有没有更好的方法来实现这个目标?
当前回答
这不是为了直接回答OP,但我想分享一些相关的想法。
我对上面@steveha的回答非常感兴趣,它似乎给出了一个鸭子打字似乎崩溃的例子。然而,仔细一想,他的例子表明duck类型很难符合,但这并不意味着str值得任何特殊处理。
毕竟,非str类型(例如,维护一些复杂递归结构的用户定义类型)可能会导致@steveha srepr函数导致无限递归。虽然承认这不大可能,但我们不能忽视这种可能性。因此,我们不应该在srepr中使用特殊的str大小写,而是应该阐明当产生无限递归时,我们希望srepr做什么。
一种合理的方法似乎是简单地打破矩列表(arg) == [arg]中srepr的递归。事实上,这将完全解决str的问题,而不需要任何isinstance。
然而,一个非常复杂的递归结构可能会导致一个无限循环,其中list(arg) == [arg]永远不会发生。因此,虽然上面的检查很有用,但还不够。我们需要对递归深度有一个硬性限制。
我的观点是,如果你打算处理任意的参数类型,通过duck类型处理str要比处理你可能(理论上)遇到的更一般的类型容易得多。因此,如果您觉得需要排除str实例,您应该要求参数是您显式指定的少数类型之一的实例。
其他回答
以“鸭子打字”的方式,怎么样
try:
lst = lst + []
except TypeError:
#it's not a list
or
try:
lst = lst + ()
except TypeError:
#it's not a tuple
分别。这避免了isinstance / hasattr自省的事情。
你也可以反过来检查:
try:
lst = lst + ''
except TypeError:
#it's not (base)string
所有变量实际上并不改变变量的内容,而是意味着重新赋值。我不确定在某些情况下这是否不可取。
有趣的是,如果lst是一个列表(不是元组),使用“in place”赋值+=在任何情况下都不会引发TypeError。这就是为什么作业是这样做的。也许有人能解释一下原因。
我倾向于这样做(如果我真的,真的必须这么做的话):
for i in some_var:
if type(i) == type(list()):
#do something with a list
elif type(i) == type(tuple()):
#do something with a tuple
elif type(i) == type(str()):
#here's your string
为了提高可读性和最佳实践,请尝试以下方法:
python - 2 - isce ()
import types
if isinstance(lst, types.ListType) or isinstance(lst, types.TupleType):
# Do something
Python3 - isinstance()
import typing
if isinstance(lst, typing.List) or isinstance(lst, typing.Tuple):
# Do something
希望能有所帮助。
这不是为了直接回答OP,但我想分享一些相关的想法。
我对上面@steveha的回答非常感兴趣,它似乎给出了一个鸭子打字似乎崩溃的例子。然而,仔细一想,他的例子表明duck类型很难符合,但这并不意味着str值得任何特殊处理。
毕竟,非str类型(例如,维护一些复杂递归结构的用户定义类型)可能会导致@steveha srepr函数导致无限递归。虽然承认这不大可能,但我们不能忽视这种可能性。因此,我们不应该在srepr中使用特殊的str大小写,而是应该阐明当产生无限递归时,我们希望srepr做什么。
一种合理的方法似乎是简单地打破矩列表(arg) == [arg]中srepr的递归。事实上,这将完全解决str的问题,而不需要任何isinstance。
然而,一个非常复杂的递归结构可能会导致一个无限循环,其中list(arg) == [arg]永远不会发生。因此,虽然上面的检查很有用,但还不够。我们需要对递归深度有一个硬性限制。
我的观点是,如果你打算处理任意的参数类型,通过duck类型处理str要比处理你可能(理论上)遇到的更一般的类型容易得多。因此,如果您觉得需要排除str实例,您应该要求参数是您显式指定的少数类型之一的实例。
在python中>3.6
import collections
isinstance(set(),collections.abc.Container)
True
isinstance([],collections.abc.Container)
True
isinstance({},collections.abc.Container)
True
isinstance((),collections.abc.Container)
True
isinstance(str,collections.abc.Container)
False