[英]How do you set a conditional in python based on datatypes?
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?我知道您可以在 python 中检查数据类型,但是如何根据数据类型设置条件? 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?例如,如果我必须编写一个对字典/列表进行排序并将所有整数相加的代码,我如何隔离搜索以仅查找整数?
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 行,我将如何设置这样的条件?
How about,怎么样,
if isinstance(x, int):
but a cleaner way would simply be但更清洁的方法就是
sum(z for z in y if isinstance(z, int))
TLDR:域名注册地址:
if isinstance(x, int):
unless you have a reason not to.使用if isinstance(x, int):
除非你有理由不这样做。if type(x) is int:
if you need exact type equality and nothing else. if type(x) is int:
如果您需要精确的类型相等而不是其他任何东西。try: ix = int(x)
if you are fine with converting to the target type.如果您可以转换为目标类型,请使用try: ix = int(x)
。There is a really big "it depends" to type-checking in Python.在 Python 中进行类型检查有一个非常大的“取决于”。 There are many ways to deal with types, and all have their pros and cons.处理类型的方法有很多种,各有优缺点。 With Python3, several more have emerged.在 Python3 中,出现了更多。
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 exact type equality.这是最严格的测试类型:它需要精确的类型相等。 Often, this is not what you want:通常,这不是您想要的:
float
would not be valid, even though it behaves like an int
for many purposes.它排除了替代类型: float
是无效的,即使它在许多用途上表现得像一个int
。int
subclass or enum
would be rejected, even though they are logically Integers.它排除了子类和抽象类型:即使它们在逻辑上是整数,也会拒绝打印漂亮的int
子类或enum
。
str
or unicode
, and Integers can be either int
or long
.这严重限制了便携性:Python2字符串可以是str
或unicode
,并且整数可以是int
或long
。Note that explicit type equality has its uses for low-level operations:需要注意的是显式类型的平等有其低级别操作的用途:
slice
.某些类型不能被子类化,例如slice
。 An explicit check is, well, more explicit here.明确的检查在这里更明确。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 dict
to dispatch actions is more extensible and can be faster (≥5-10 types) than explicit checks.当有多个类要检查时,使用dict
来分派动作比显式检查更具可扩展性并且可以更快(≥5-10 类型)。 This is especially useful for conversions and serialisation:这对于转换和序列化特别有用:
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)
The idiomatic type test uses the isinstance
builtin :惯用类型测试使用isinstance
内置:
if isinstance(x, int):
This check is both exact and performant.这种检查既准确又高效。 This is most often what people want for checking types:这通常是人们想要检查类型的内容:
int
subclass would still pass this test.打印漂亮的int
子类仍将通过此测试。isinstance(x, (int, long))
gets you all builtin integers.在 Python2 中,执行isinstance(x, (int, long))
可以获得所有内置整数。Most importantly, the downsides are negligible most of the time:最重要的是,在大多数情况下,缺点可以忽略不计:
isinstance(x, list)
when any sequence (eg tuple
) or even iterable (eg a generator
) would do as well.它很容易变得过于严格:许多人在任何序列(例如tuple
)甚至可迭代(例如generator
)也可以这样做时检查isinstance(x, list)
。 This is more of a concern for general purpose libraries than scripts or applications.对于通用库而言,这比脚本或应用程序更值得关注。If you already have a type, issubclass
behaves the same:如果您已经有一个类型,则issubclass
行为相同:
if issubclass(x_type, int):
Python has a concept of abstract base classes . Python 有一个抽象基类的概念。 Loosely speaking, these express the meaning of types, not their hierarchy:粗略地说,这些表达了类型的含义,而不是它们的层次结构:
if isinstance(x, numbers.Real): # accept anything you can sum up like a number
In other words, type(x) does not necessarily inherit from numbers.Real
but must behave like it.换句话说, type(x) 不一定从numbers.Real
继承,但必须表现得像它。 Still, this is a very complex and difficult concept:尽管如此,这是一个非常复杂和困难的概念:
int
most of the time.大多数情况下,Integer 只是一个int
。However, it is incredibly useful for generic libraries and abstractions.但是,它对于通用库和抽象非常有用。
dict
restricts you to a specific in-memory type.如果您只需要按键查找内容, dict
您限制为特定的内存类型。 By contrast, collections.abc.Mapping
also includes database wrappers, large disk-backed dictionaries, lazy containers, ... - and dict
.相比之下, collections.abc.Mapping
还包括数据库包装器、大型磁盘支持的字典、惰性容器、... - 和dict
。collections.abc.Iterable
, they all work in a for
loop.但是如果你根据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 版本之外的任何内容。
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.这实际上不是类型检查,但通常用于相同的目的。
float
to int
.它在转换错误类型方面有一些有限的回旋余地,例如将float
专门化为int
。int
.它可以在您不知道哪些类型符合int
。The major downside is that it is an explicit transformation.主要的缺点是它是一个显式转换。
str
containing a literal.您可以默默地接受“错误”值,例如转换包含文字的str
。float
to int
when you just need numbers.它不必要地转换甚至足够好的类型,例如,当您只需要数字时,将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.如果您粗略地知道您的输入是什么,并且必须保证您的输出,则效果最佳。
Sometimes the goal of type checking is just to select an appropriate function.有时类型检查的目标只是选择一个合适的函数。 In this case, function dispatch such as functools.singledispatch
allows 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 isinstance
and dict
dispatch.这是isinstance
和dict
调度的组合。 It is most useful for larger applications:它对于较大的应用程序最有用:
Still, it doesn't come without its downsides:尽管如此,它也并非没有缺点:
dict
lookup.即使是预热的调度表也比手写的 if/else 或dict
查找慢。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 somelist
should never have put non-numbers into it.在这里, somelist
的来源somelist
应该将非数字放入其中。
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.两者都工作正常。
您可以像这样简单地使用类型和等号运算符
if (type(x) == int):
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__']
You can use the type function on both sides of the operator.您可以在运算符的两侧使用 type 函数。 Like this:像这样:
if type(x) == type(1):
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.