你如何根据数据类型在python中设置条件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14113187/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 10:30:45  来源:igfitidea点击:

How do you set a conditional in python based on datatypes?

pythontypesconditional

提问by 01110100

This question seems mind-boggling simple, yet I can't figure it out. I know you can check datatypes in python, but how can you set a conditional based on the datatype? For instance, if I have to write a code that sorts through a dictionary/list and adds up all the integers, how do I isolate the search to look for only integers?

这个问题看起来很简单,但我想不通。我知道您可以在 python 中检查数据类型,但是如何根据数据类型设置条件?例如,如果我必须编写一个对字典/列表进行排序并将所有整数相加的代码,我如何隔离搜索以仅查找整数?

I guess a quick example would look something like this:

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

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

So for line 3, how would I set such a conditional?

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

采纳答案by Jakob Bowyer

How about,

怎么样,

if isinstance(x, int):

but a cleaner way would simply be

但更清洁的方法就是

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

回答by jimf

Easy - use types.

易于使用的类型。

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

Here's a quick dir(types):

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

['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__']

回答by Joonazan

You can use the type function on both sides of the operator. Like this:

您可以在运算符的两侧使用 type 函数。像这样:

if type(x) == type(1):

回答by MisterMiyagi

TLDR:

域名注册地址:

  • Use if isinstance(x, int):unless you have a reason not to.
  • Use if type(x) is int:if you need exact type equality and nothing else.
  • Use try: ix = int(x)if you are fine with converting to the target type.
  • if isinstance(x, int):除非您有理由不使用,否则请使用。
  • 使用if type(x) is int:,如果您需要确切类型平等,没有别的。
  • 使用try: ix = int(x),如果你是转换为目标类型的罚款。


There is a really big "it depends" to type-checking in Python. There are many ways to deal with types, and all have their pros and cons. With Python3, several more have emerged.

在 Python 中进行类型检查有一个非常大的“取决于”。处理类型的方法有很多种,各有优缺点。在 Python3 中,出现了更多。

Explicit type equality

显式类型相等

Types are first-class objects, and you can treat them like any other value. So if you want the type of something to be equal to int, just test for it:

类型是一流的对象,您可以像对待任何其他值一样对待它们。因此,如果您希望某事物的类型等于int,只需对其进行测试:

if type(x) is int:

This is the most restrictive type of testing: it requires exacttype equality. Often, this is not what you want:

这是最严格的测试类型:它需要精确的类型相等。通常,这不是您想要的:

  • It rules out substitute types: a floatwould not be valid, even though it behaves like an intfor many purposes.
  • It rules out subclasses and abstract types: a pretty-printing intsubclass or enumwould be rejected, even though they are logically Integers.
    • This severely limits portability: Python2 Strings can be eitherstror unicode, and Integers can be eitherintor long.
  • 它排除了替代类型:afloat将是无效的,即使它的行为int在许多方面都与 an 相似。
  • 它排除了子类和抽象类型:打印漂亮的int子类或enum将被拒绝,即使它们在逻辑上是整数。
    • 这严重限制了便携性:Python2字符串可以是任一strunicode,和整数可以是任一intlong

Note that explicit type equality hasits uses for low-level operations:

需要注意的是显式类型的平等其低级别操作的用途:

  • Some types cannotbe subclassed, such as slice. An explicit check is, well, more explicit here.
  • Some low-level operations, such as serialisation or C-APIs, require specific types.
  • 某些类型不能被子类化,例如slice. 明确的检查在这里更明确。
  • 一些低级操作,例如序列化或 C-API,需要特定类型。

Variants

变体

A comparison can also be performed against the __class__attribute:

也可以对__class__属性进行比较:

if x.__class__ is int:

Note if a class defines a __class__property, this is not the same as type(x).

请注意,如果一个类定义了一个__class__属性,则这与type(x).

When there are several classes to check for, using a dictto dispatch actions is more extensible and can be faster (≥5-10 types) than explicit checks. This is especially useful for conversions and serialisation:

当有多个类要检查时,使用 adict来分派动作比显式检查更具可扩展性并且可以更快(≥5-10 类型)。这对于转换和序列化特别有用:

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)

Instance check on explicit types

显式类型的实例检查

The idiomatic type test uses the isinstancebuiltin:

惯用类型测试使用isinstance内置

if isinstance(x, int):

This check is both exact and performant. This is most often what people wantfor checking types:

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

  • It handles subtypes properly. A pretty-printing intsubclass would still pass this test.
  • It allows checking multiple types at once. In Python2, doing isinstance(x, (int, long))gets you all builtin integers.
  • 它正确处理子类型。一个漂亮的打印int子类仍然会通过这个测试。
  • 它允许一次检查多种类型。在 Python2 中,这样做isinstance(x, (int, long))会为您提供所有内置整数。

Most importantly, the downsides are negligible most of the time:

最重要的是,在大多数情况下,缺点可以忽略不计:

  • It still accepts funky subclasses that behave in weird ways. Since anythingcan be made to behave in weird ways, this is futile to guard against.
  • It can easily be toorestrictive: many people check for isinstance(x, list)when any sequence (e.g. tuple) or even iterable (e.g. a generator) would do as well. This is more of a concern for general purpose libraries than scripts or applications.
  • 它仍然接受行为怪异的时髦子类。由于任何事物都可能以奇怪的方式运行,因此无法防范。
  • 它很容易变得过于严格:许多人会检查isinstance(x, list)何时任何序列(例如tuple)甚至可迭代(例如 a generator)也可以这样做。对于通用库而言,这比脚本或应用程序更值得关注。

Variant

变体

If you already have a type, issubclassbehaves the same:

如果您已经有一个类型,则issubclass行为相同:

if issubclass(x_type, int):

Instance check on abstract type

抽象类型的实例检查

Python has a concept of abstract base classes. Loosely speaking, these express the meaning of types, not their hierarchy:

Python 有一个抽象基类的概念。粗略地说,这些表达了类型的含义,而不是它们的层次结构:

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

In other words, type(x) does not necessarily inheritfrom numbers.Realbut must behavelike it. Still, this is a very complex and difficult concept:

换句话说, type(x) 不一定继承numbers.Real但必须表现得像它。尽管如此,这是一个非常复杂和困难的概念:

  • It is often overkill if you are looking for basic types. An Integer is simply an intmost of the time.
  • People coming from other languages often confuse its concepts.
    • Distinguishing it from e.g. C++, the emphasis is abstract baseclass as opposed to abstractbase class.
    • ABCs can be used like Java interfaces, but may still have concrete functionality.
  • 如果您正在寻找基本类型,这通常是矫枉过正。int大多数情况下,整数只是一个。
  • 来自其他语言的人经常混淆它的概念。
    • 将其与例如 C++ 区分开来,重点是抽象基类而不是抽象基类。
    • ABC 可以像 Java 接口一样使用,但可能仍然具有具体的功能。

However, it is incredibly useful for generic libraries and abstractions.

但是,它对于通用库和抽象非常有用。

  • Many functions/algorithms do not need explicit types, just their behaviour.
    • If you just need to look up things by key, dictrestricts you to a specific in-memory type. By contrast, collections.abc.Mappingalso includes database wrappers, large disk-backed dictionaries, lazy containers, ... - and dict.
  • It allows expressing partial type constraints.
    • There is no strict base type implementing iteration. But if you check objects against collections.abc.Iterable, they all work in a forloop.
  • It allows creating separate, optimised implementations that appear as the same abstract type.
  • 许多函数/算法不需要显式类型,只需要它们的行为。
    • 如果您只需要按键查找内容,dict请将您限制为特定的内存类型。相比之下,collections.abc.Mapping还包括数据库包装器、大型磁盘支持的字典、惰性容器、... - 和dict.
  • 它允许表达部分类型约束。
    • 没有严格的基本类型实现迭代。但是,如果您根据 来检查对象collections.abc.Iterable,则它们都在for循环中工作。
  • 它允许创建单独的、优化的实现,这些实现显示为相同的抽象类型。

While it is usually not needed for throwaway scripts, I would highly recommend using this for anything that lives beyond a few python releases.

虽然一次性脚本通常不需要它,但我强烈建议将它用于除几个 Python 版本之外的任何内容。

Tentative conversion

暂定转换

The idiomatic way of handling types is not to test them, but to assume they are compatible. If you already expect some wrong types in your input, simply skip everything that is not compatible:

处理类型的惯用方式不是测试它们,而是假设它们是兼容的。如果您已经预料到输入中有一些错误的类型,只需跳过所有不兼容的内容:

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

This is not actually a type check, but usually serves the same intention.

这实际上不是类型检查,但通常用于相同的目的。

  • It guaranteesyou have the expected type in your output.
  • It has some limited leeway in converting wrong types, e.g. specialising floatto int.
  • It works without you knowing which types conform to int.
  • 保证您在输出中具有预期的类型。
  • 它在将错误类型,例如专业一些有限的回旋余地floatint
  • 它在您不知道哪些类型符合int.

The major downside is that it is an explicit transformation.

主要的缺点是它是一个显式转换。

  • You can silently accept "wrong" values, e.g. converting a strcontaining a literal.
  • It needlessly converts even types that would be good enough, e.g. floatto intwhen you just need numbers.
  • 您可以默默地接受“错误”值,例如转换str包含文字的 a。
  • 它不必要地转换甚至足够好的类型,例如floatint当您只需要数字时。

Conversion is an effective tool for some specific use cases. It works best if you know roughly what your input is, and must make guarantees about your output.

转换是某些特定用例的有效工具。如果您粗略地知道您的输入是什么,并且必须保证您的输出,则效果最佳。

Function dispatch

函数调度

Sometimes the goal of type checking is just to select an appropriate function. In this case, function dispatch such as functools.singledispatchallows specialising function implementations for specific types:

有时类型检查的目的只是为了选择一个合适的函数。在这种情况下,函数分派例如functools.singledispatch允许特定类型的专门函数实现:

@singledispatch
def append_int(value, sequence):
    return

@append_int.register
def _(value: int, sequence):
    sequence.append(value)

This is a combination of isinstanceand dictdispatch. It is most useful for larger applications:

这是isinstancedict调度的结合。它对于较大的应用程序最有用:

  • It keeps the site of usage small, regardless of the number of dispatched types.
  • It allows registering specialisations for additional types later, even in other modules.
  • 无论调度类型的数量如何,它都会使使用站点保持较小。
  • 它允许稍后为其他类型注册特化,甚至在其他模块中。

Still, it doesn't come without its downsides:

尽管如此,它也并非没有缺点:

  • Originating in functional and strongly typed languages, many Python programmers are not familiar with single- or even multiple-dispatch.
  • Dispatches require separate functions, and are therefore not suitable to be defined at the site of usage.
    • Creating the functions and "warming up" the dispatch cache takes notable runtime overhead. Dispatch functions should be defined once and re-used often.
    • Even a warmed up dispatch table is slower than a hand-written if/else or dictlookup.
  • 许多 Python 程序员起源于函数式和强类型语言,并不熟悉单分派甚至多分派。
  • 调度需要单独的功能,因此不适合在使用地点定义。
    • 创建函数和“预热”调度缓存需要显着的运行时开销。调度函数应该定义一次并经常重复使用。
    • 即使是预热的调度表也比手写的 if/else 或dict查找慢。

Controlling the input

控制输入

The best course of action is to ensure you never have to check for type in the first place. This is a bit of a meta-topic, as it depends strongly on the use case.

最好的做法是确保您永远不必首先检查类型。这有点像元主题,因为它在很大程度上取决于用例。

Here, the source of somelistshould never have put non-numbers into it.

在这里,源不somelist应该把非数字放进去。

回答by Naga Sreyas

let me declare variable x of type int

让我声明 int 类型的变量 x

x = 2
if type(x) == type(1) or isinstance(x, int):  
    # do something

Both works fine.

两者都工作正常。