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?
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?
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 type(x) is int:
if you need exact type equality and nothing else. try: ix = int(x)
if you are fine with converting to the target type.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.
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:
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.int
subclass or enum
would be rejected, even though they are logically Integers.
str
or unicode
, and Integers can be either int
or long
.Note that explicit type equality has its uses for low-level operations:
slice
. An explicit check is, well, more explicit here.A comparison can also be performed against the __class__
attribute:
if x.__class__ is int:
Note if a class defines a __class__
property, this is not the same as 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. 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 :
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.isinstance(x, (int, long))
gets you all builtin integers.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. This is more of a concern for general purpose libraries than scripts or applications.If you already have a type, issubclass
behaves the same:
if issubclass(x_type, int):
Python has a concept of abstract base classes . 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. Still, this is a very complex and difficult concept:
int
most of the time.However, it is incredibly useful for generic libraries and abstractions.
dict
restricts you to a specific in-memory type. By contrast, collections.abc.Mapping
also includes database wrappers, large disk-backed dictionaries, lazy containers, ... - and dict
.collections.abc.Iterable
, they all work in a for
loop.While it is usually not needed for throwaway scripts, I would highly recommend using this for anything that lives beyond a few python releases.
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
.int
.The major downside is that it is an explicit transformation.
str
containing a literal.float
to int
when you just need numbers.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:
@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. It is most useful for larger applications:
Still, it doesn't come without its downsides:
dict
lookup.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.
let me declare variable x of type int
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. Like this:
if type(x) == type(1):
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.