你如何在基于数据类型的python中设置条件?

这个问题似乎令人难以置信,但我无法弄清楚。 我知道你可以在python中检查数据类型,但是如何根据数据类型设置一个条件? 例如,如果我必须编写一个通过字典/列表进行排序并将所有整数相加的代码,那么如何将搜索分离为仅查找整数?

我想一个简单的例子看起来像这样:

y = []
for x in somelist:
    if type(x) == <type 'int'>:  ### <--- psuedo-code line
    y.append(x)
print sum(int(z) for z in y)

所以对于第3行,我将如何设置这样的条件?


怎么样,

if isinstance(x, int):

但一个更清洁的方式将是简单的

sum(z for z in y if isinstance(z, int))

有一个非常大的“它依赖于”在Python中进行类型检查。 处理类型有很多种方法,都有其优点和缺点。 随着Python3,还出现了更多。

  • 显式类型相等
  • 类型是一流的对象,你可以像对待任何其他值一样对待它们。 所以如果你想要的东西的类型等于int ,只需测试它:

    if type(x) == int:
    

    这是最严格的测试类型:它要求确切的类型相等。 通常情况下,这不是你想要的:

  • 它排除了替代类型:一个float不会是有效的,即使它像一个int多种用途。
  • 它排除了子类和抽象类型:即使它们是逻辑上的整数,漂亮打印的int子类或enum也会被拒绝。
  • 这严重限制了可移植性:Python2字符串可以是strunicode ,整数可以是intlong
  • 请注意,显式类型相等性用于低级操作:

  • 有些类型不能被分类,如slice 。 明确的检查在这里更加明确。
  • 一些低级操作(如序列化或C-API)需要特定的类型。
  • 变种

    __class__执行比较会稍微快一点:

    if x.__class__ == int:
    

    当需要检查多个类时,使用dict来分派操作比显式检查要快得多。 这对转换和序列化特别有用:

    dispatch_dict = {float: round, str: int, int: lambda x: x}
    def convert(x):
        converter = self.dispatch_dict[type(x)]  # lookup callable based on type
        return converter(x)
    
  • 实例检查显式类型
  • 惯用类型测试使用isinstance内置:

    if isinstance(x, int):
    

    该检查既准确又高效。 这通常是人们想要检查的类型:

  • 它正确处理亚型。 漂亮的int子类仍然可以通过这个测试。
  • 它允许一次检查多种类型。 在Python2中,执行isinstance(x, (int, long))会得到所有内置整数。
  • 最重要的是,大多数时候这些缺点是微不足道的:

  • 它仍然接受奇怪的方式行事的时髦的子类。 由于任何事情都可以用怪异的方式表现出来,所以这是徒劳的。
  • 它可能很容易过于严格:许多人在任何序列(例如tuple )或甚至可迭代(例如generator )都可以执行时检查isinstance(x, list) 。 对于通用库而言,这比脚本或应用程序更受关注。
  • 变种

    如果你已经有了一个类型, issubclass行为是一样的:

    if issubclass(x_type, int):
    
  • 实例检查抽象类型
  • Python有一个抽象基类的概念。 松散地说,这些表达了类型的含义,而不是它们的层次结构:

    if isinstance(x, numbers.Real):  # accept anything you can sum up
    

    换句话说,类型(X)不一定继承numbers.Real但必须表现得像它。 不过,这是一个非常复杂和困难的概念:

  • 如果你正在寻找基本类型,这往往是矫枉过正的。 一个整数仅仅是一个int的大部分时间。
  • 来自其他语言的人经常会混淆其概念。
  • 与C ++区分开来,重点是抽象基类,而不是抽象基类。
  • 然而,它对于通用库和抽象是非常有用的。

  • 许多函数/算法不需要显式类型,只需要它们的行为。
  • 如果您只需要按键查找, dict将您限制为特定的内存类型。 相比之下, collections.abc.Mapping还包括数据库包装器,大型磁盘备份字典,懒惰容器......以及dict
  • 它允许表达部分类型约束。
  • 没有严格的基本类型实现迭代。 但是,如果您针对collections.abc.Iterable检查对象,则它们都在for循环中工作。
  • 它允许创建显示为相同抽象类型的单独的优化实现。
  • 虽然通常不需要一次性脚本,但我强烈推荐将它用于超越几个python版本的任何东西。

  • 暂定转换
  • 处理类型的惯用方式不是测试它们,而是假定它们是兼容的。 如果您已经在输入中预期了一些错误的类型,只需跳过不兼容的所有内容即可:

    try:
        ix = int(x)
    except (ValueError, TypeError):
        continue  # not compatible with int, try the next one
    else:
        a.append(ix)
    

    这实际上不是一种类型检查,但通常具有相同的意图。

  • 它可以保证您的输出具有预期的类型。
  • 它在转换错误类型方面有一些有限的余地,例如专门将float转换为int
  • 它在你不知道哪些类型符合int
  • 主要的缺点是它是一个明显的转变。

  • 你可以默默接受“错误”的值,例如转换一个包含文字的str
  • 它不必要地转换甚至足够好的类型,例如,当你只需要数字时就可以floatint
  • 对于某些特定用例,转换是一种有效的工具。 如果你大致了解你的输入是什么,并且必须对你的输出做出保证,那么它效果最好。

  • 控制输入
  • 最好的行动方式是确保你不必首先检查类型。 这是一个元主题,因为它很大程度上取决于用例。

    在这里, somelist的来源somelist应该放入非数字。


    简单易用的类型。

    import types
    k = 5
    if(type(k)==types.IntType):
       print "int"
    

    这里有一个快速目录(类型):

    ['BooleanType', 'BufferType', 'BuiltinFunctionType', 'BuiltinMethodType', 'ClassType', 'CodeType', 'ComplexType', 'DictProxyType', 'DictType', 'DictionaryType', 'EllipsisType', 'FileType', 'FloatType', 'FrameType', 'FunctionType', 'GeneratorType', 'GetSetDescriptorType', 'InstanceType', 'IntType', 'LambdaType', 'ListType', 'LongType', 'MemberDescriptorType', 'MethodType', 'ModuleType', 'NoneType', 'NotImplementedType', 'ObjectType', 'SliceType', 'StringType', 'StringTypes', 'TracebackType', 'TupleType', 'TypeType', 'UnboundMethodType', 'UnicodeType', 'XRangeType', '__builtins__', '__doc__', '__file__', '__name__', '__package__']
    
    链接地址: http://www.djcxy.com/p/54241.html

    上一篇: How do you set a conditional in python based on datatypes?

    下一篇: isinstance(foo,bar) vs type(foo) is bar