我需要知道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提醒我,这是经常清洁剂使用的字典(作为case语句)比如果/ elif的/其他系列.
让我详细说明我的用例.如果变量是一个字符串,我需要将它放在一个列表中.如果它是一个字典,我需要一个唯一值的列表.这是我想出的:
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()
功能?
如果有人将unicode字符串传递给您的函数会发生什么?还是一个源自dict的类?或者是一个实现类似dict的界面的类?以下代码涵盖前两种情况.如果您在使用Python 2.6,你可能想使用collections.Mapping
,而不是dict
作为每ABC PEP.
def value_list(x): if isinstance(x, dict): return list(set(x.values())) elif isinstance(x, basestring): return [x] else: return None
type(dict())
说"做一个新的字典,然后找出它的类型".说"dict"更快.但是如果你只想检查类型,那么更惯用的方法就是dict
.
注意,这isinstance(x, dict)
也包括子类(感谢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
顺便说一下是运营商.但是,类型检查(如果你想调用它)通常是通过在try-except子句中包装特定于类型的测试来完成的,因为它不是那么重要的变量类型,而是你是否可以做某些事情.有与否的东西.
isinstance优先于类型,因为当你将一个对象实例与它的超类进行比较时,它也会评估为True,这基本上意味着你不必特别使用旧代码将它与dict或str子类一起使用.
例如:
>>> class a_dict(dict): ... pass ... >>> type(a_dict()) == type(dict()) False >>> isinstance(a_dict(), dict) True >>>
当然,在某些情况下,您可能不会想要这种行为,但这些行为 - 实际上 - 比您想要它的情况要少得多.
我想我会采用鸭子打字方式 - "如果它像鸭子一样走路,它会像鸭子一样嘎嘎叫,它是一只鸭子".这样您就不必担心字符串是unicode还是ascii.
这是我要做的:
In [53]: s='somestring' In [54]: u=u'someunicodestring' In [55]: d={} In [56]: for each in s,u,d: if hasattr(each, 'keys'): print list(set(each.values())) elif hasattr(each, 'lower'): print [each] else: print "error" ....: ....: ['somestring'] [u'someunicodestring'] []
这里的专家欢迎评论这种类型的鸭子使用,我一直在使用它,但最近介绍了它背后的确切概念,并对此非常兴奋.所以我想知道这是不是太过分了.
我认为实际上可能更喜欢
if isinstance(x, str): do_something_with_a_string(x) elif isinstance(x, dict): do_somethting_with_a_dict(x) else: raise ValueError
2替代形式,取决于你的代码中的一个或另一个可能被认为比那更好.一个是在你跳跃之前不要看
try: one, two = tupleOrValue except TypeError: one = tupleOrValue two = None
另一种方法来自Guido,是一种函数重载,使代码更加开放.
http://www.artima.com/weblogs/viewpost.jsp?thread=155514