你如何根据数据类型在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
How do you set a conditional in python based on datatypes?
提问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 anintfor many purposes. - It rules out subclasses and abstract types: a pretty-printing
intsubclass orenumwould be rejected, even though they are logically Integers.- This severely limits portability: Python2 Strings can be either
strorunicode, and Integers can be eitherintorlong.
- This severely limits portability: Python2 Strings can be either
- 它排除了替代类型:a
float将是无效的,即使它的行为int在许多方面都与 an 相似。 - 它排除了子类和抽象类型:打印漂亮的
int子类或enum将被拒绝,即使它们在逻辑上是整数。- 这严重限制了便携性:Python2字符串可以是任一
str或unicode,和整数可以是任一int或long。
- 这严重限制了便携性:Python2字符串可以是任一
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. agenerator) would do as well. This is more of a concern for general purpose libraries than scripts or applications.
- 它仍然接受行为怪异的时髦子类。由于任何事物都可能以奇怪的方式运行,因此无法防范。
- 它很容易变得过于严格:许多人会检查
isinstance(x, list)何时任何序列(例如tuple)甚至可迭代(例如 agenerator)也可以这样做。对于通用库而言,这比脚本或应用程序更值得关注。
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, ... - anddict.
- If you just need to look up things by key,
- 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 aforloop.
- There is no strict base type implementing iteration. But if you check objects against
- 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
floattoint. - It works without you knowing which types conform to
int.
- 它保证您在输出中具有预期的类型。
- 它在将错误类型,例如专业一些有限的回旋余地
float来int。 - 它在您不知道哪些类型符合
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.
floattointwhen you just need numbers.
- 您可以默默地接受“错误”值,例如转换
str包含文字的 a。 - 它不必要地转换甚至足够好的类型,例如
float,int当您只需要数字时。
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:
这是isinstance和dict调度的结合。它对于较大的应用程序最有用:
- 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.
两者都工作正常。

