我需要知道Python中的变量是字符串还是字典。下面的代码有问题吗?

if type(x) == type(str()):
    do_something_with_a_string(x)
elif type(x) == type(dict()):
    do_somethting_with_a_dict(x)
else:
    raise ValueError

更新:我接受avisser的答案(尽管如果有人解释为什么isinstance比type(x) is更受欢迎,我会改变主意)。

但是感谢nakedfanatic提醒我,使用dict(作为case语句)通常比使用if/elif/else系列更简洁。

让我详细说明我的用例。如果一个变量是一个字符串,我需要把它放在一个列表中。如果是字典,我需要一个唯一值的列表。这是我想到的:

def value_list(x):
    cases = {str: lambda t: [t],
             dict: lambda t: list(set(t.values()))}
    try:
        return cases[type(x)](x)
    except KeyError:
        return None

如果isinstance是首选,你将如何编写这个value_list()函数?


当前回答

你可能想要检查typcheck。 http://pypi.python.org/pypi/typecheck

Python类型检查模块

这个包为Python函数、方法和生成器提供了强大的运行时类型检查工具。不需要自定义预处理器或改变语言,类型检查包允许程序员和质量保证工程师对他们的代码的输入和输出做出精确的断言。

其他回答

我觉得还是去做比较好

if isinstance(x, str):
    do_something_with_a_string(x)
elif isinstance(x, dict):
    do_somethting_with_a_dict(x)
else:
    raise ValueError

另一种形式,取决于你的代码,一种或另一种甚至可能被认为是更好的。一是三思而后行

try:
  one, two = tupleOrValue
except TypeError:
  one = tupleOrValue
  two = None

另一种方法来自Guido,它是函数重载的一种形式,使您的代码更加开放。

http://www.artima.com/weblogs/viewpost.jsp?thread=155514

我一直在用另一种方法:

from inspect import getmro
if (type([]) in getmro(obj.__class__)):
    # This is a list, or a subclass of...
elif (type{}) in getmro(obj.__class__)):
    # This one is a dict, or ...

我不记得我为什么用this而不是isinstance了。

isinstance比type更可取,因为当你比较对象实例和它的超类时,它的值也为True,这基本上意味着你不必为dict或str子类使用它而对旧代码进行特殊处理。

例如:

 >>> class a_dict(dict):
 ...     pass
 ... 
 >>> type(a_dict()) == type(dict())
 False
 >>> isinstance(a_dict(), dict)
 True
 >>> 

当然,在某些情况下,您可能不希望出现这种行为,但希望这些情况比您确实希望出现这种行为的情况要少得多。

Type (dict())表示“创建一个新的dict,然后找出它的类型”。直接说dict会更快。 但如果你只是想检查类型,更习惯的方法是isinstance(x, dict)。

注意,isinstance也包括子类(感谢Dustin):

class D(dict):
    pass

d = D()
print("type(d) is dict", type(d) is dict)  # -> False
print("isinstance (d, dict)", isinstance(d, dict))  # -> True

Python中的内置类型有内置名称:

>>> s = "hallo"
>>> type(s) is str
True
>>> s = {}
>>> type(s) is dict
True

顺便说一句,注意is操作符。然而,类型检查(如果你想这么称呼它)通常是通过在try-except子句中包装特定于类型的测试来完成的,因为重要的不是变量的类型,而是你是否可以用它做某些事情。