这是我通常所做的,以确定输入是一个列表/元组-而不是一个str。因为很多次我偶然发现错误,其中一个函数错误地传递了一个str对象,而目标函数在lst中执行x,假设lst实际上是一个列表或元组。
assert isinstance(lst, (list, tuple))
我的问题是:有没有更好的方法来实现这个目标?
这是我通常所做的,以确定输入是一个列表/元组-而不是一个str。因为很多次我偶然发现错误,其中一个函数错误地传递了一个str对象,而目标函数在lst中执行x,假设lst实际上是一个列表或元组。
assert isinstance(lst, (list, tuple))
我的问题是:有没有更好的方法来实现这个目标?
当前回答
H = "Hello"
if type(H) is list or type(H) is tuple:
## Do Something.
else
## Do Something.
其他回答
我倾向于这样做(如果我真的,真的必须这么做的话):
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
duck-typing的另一个版本,用于帮助区分类似字符串的对象和其他类似序列的对象。
类字符串对象的字符串表示就是字符串本身,所以你可以检查你是否从str构造函数返回了一个相等的对象:
# If a string was passed, convert it to a single-element sequence
if var == str(var):
my_list = [var]
# All other iterables
else:
my_list = list(var)
这应该适用于所有与str兼容的对象和所有类型的可迭代对象。
这不是为了直接回答OP,但我想分享一些相关的想法。
我对上面@steveha的回答非常感兴趣,它似乎给出了一个鸭子打字似乎崩溃的例子。然而,仔细一想,他的例子表明duck类型很难符合,但这并不意味着str值得任何特殊处理。
毕竟,非str类型(例如,维护一些复杂递归结构的用户定义类型)可能会导致@steveha srepr函数导致无限递归。虽然承认这不大可能,但我们不能忽视这种可能性。因此,我们不应该在srepr中使用特殊的str大小写,而是应该阐明当产生无限递归时,我们希望srepr做什么。
一种合理的方法似乎是简单地打破矩列表(arg) == [arg]中srepr的递归。事实上,这将完全解决str的问题,而不需要任何isinstance。
然而,一个非常复杂的递归结构可能会导致一个无限循环,其中list(arg) == [arg]永远不会发生。因此,虽然上面的检查很有用,但还不够。我们需要对递归深度有一个硬性限制。
我的观点是,如果你打算处理任意的参数类型,通过duck类型处理str要比处理你可能(理论上)遇到的更一般的类型容易得多。因此,如果您觉得需要排除str实例,您应该要求参数是您显式指定的少数类型之一的实例。
assert (type(lst) == list) | (type(lst) == tuple), "Not a valid lst type, cannot be 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
希望能有所帮助。