当前位置:  开发笔记 > 编程语言 > 正文

检查Python变量类型的最佳(惯用)方法是什么?

如何解决《检查Python变量类型的最佳(惯用)方法是什么?》经验,为你挑选了6个好方法。

我需要知道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()功能?



1> Suraj..:

如果有人将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


collections.Mapping ABC提供了一种检查对象是否像dict一样的简单方法.代码的变化是用`isinstance(x,collections.Mapping)`替换`isinstance(x,dict)`.这提供了matting对象的额外好处,这些对象不是从dict派生的,而是提供类似的接口.
很高兴看到collections.Mapping如何进入这个讨论.它的优点是什么?我们能看到一些示例代码,以了解它的比较方式吗?ABC PEP链接在理论上相当沉重,当目标是简单地测试某些东西是字典还是字符串时,消耗相当多.是否需要额外的努力来实现ABC,并且(特别是对于一个简单的用例)是值得的额外努力?

2> 小智..:

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


@Daryl http://codepad.org/WS6BWUa5
"isinstance(x,dict)"比"type(x)是dict"更好吗?为什么?

3> Albert Visse..:

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

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

顺便说一下运营商.但是,类型检查(如果你想调用它)通常是通过在try-except子句中包装特定于类型的测试来完成的,因为它不是那么重要的变量类型,而是你是否可以做某些事情.有与否的东西.


正如其他人提到的那样,首选方法是使用isinstance builtin函数.
为什么选择isinstance?
isinstance可以在任何类/类型上完成,包括你自己定义的类,而内置类型名称数量有限

4> Dirk Stoop..:

isinstance优先于类型,因为当你将一个对象实例与它的超类进行比较时,它也会评估为True,这基本上意味着你不必特别使用旧代码将它与dict或str子类一起使用.

例如:

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

当然,在某些情况下,您可能不会想要这种行为,但这些行为 - 实际上 - 比您想要它的情况要少得多.



5> JV...:

我想我会采用鸭子打字方式 - "如果它像鸭子一样走路,它会像鸭子一样嘎嘎叫,它是一只鸭子".这样您就不必担心字符串是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']
[]

这里的专家欢迎评论这种类型的鸭子使用,我一直在使用它,但最近介绍了它背后的确切概念,并对此非常兴奋.所以我想知道这是不是太过分了.


如果我们担心这种事情,这似乎可能会产生误报.即...我的'钢琴'课也有'钥匙'

6> Ed...:

我认为实际上可能更喜欢

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

推荐阅读
周扒pi
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有