我需要确定给定的 Python 变量是否是本机类型的实例:str
, int
, float
, bool
, list
,dict
等等。有优雅的方法吗?
或者这是唯一的方法:
if myvar in (str, int, float, bool):
# do something
这是一个老问题,但似乎没有一个答案真正回答了特定问题:“(如何)确定 Python 变量是否是内置类型的实例”。请注意,它不是“特定/给定内置类型的 [...]”,而是.
确定给定对象是否是内置类型/类的实例的正确方法是检查对象的类型是否恰好在模块中定义__builtin__
。
def is_builtin_class_instance(obj):
return obj.__class__.__module__ == '__builtin__'
警告:如果obj
是类而不是实例,则无论该类是否内置,都将返回 True,因为类也是一个对象,是type
(ie AnyClass.__class__
is type
) 的一个实例。
并不是说我知道你为什么要这样做,因为 Python 中没有任何“简单”类型,它都是对象。但这有效:
type(theobject).__name__ in dir(__builtins__)
但是明确列出类型可能会更好,因为它更清晰。甚至更好:更改应用程序,这样您就不需要知道其中的区别。
更新:需要解决的问题是如何为对象制作序列化器,即使是那些内置的。做到这一点的最好方法不是制作一个以不同方式处理内置函数的大型 phat 序列化程序,而是根据类型查找序列化程序。
像这样的东西:
def IntSerializer(theint):
return str(theint)
def StringSerializer(thestring):
return repr(thestring)
def MyOwnSerializer(value):
return "whatever"
serializers = {
int: IntSerializer,
str: StringSerializer,
mymodel.myclass: MyOwnSerializer,
}
def serialize(ob):
try:
return ob.serialize() #For objects that know they need to be serialized
except AttributeError:
# Look up the serializer amongst the serializer based on type.
# Default to using "repr" (works for most builtins).
return serializers.get(type(ob), repr)(ob)
通过这种方式,您可以轻松添加新的序列化程序,并且代码易于维护和清晰,因为每种类型都有自己的序列化程序。请注意,某些类型是内置的这一事实如何变得完全无关紧要。:)
实现这一点的最好方法是在一个名为primitiveTypes
and 的元组列表中收集类型:
if isinstance(myvar, primitiveTypes): ...
该types
模块包含所有重要类型的集合,可以帮助构建列表/元组。
您似乎有兴趣确保 simplejson 将处理您的类型。这是由
try:
json.dumps( object )
except TypeError:
print "Can't convert", object
这比试图猜测您的 JSON 实现处理哪些类型更可靠。
什么是 Python 中的“本机类型”?请不要将您的代码基于类型,使用Duck Typing。
types
您可以按模块访问所有这些类型:
`builtin_types = [ i for i in types.__dict__.values() if isinstance(i, type)]`
types
提醒一下,先导入模块
def isBuiltinTypes(var):
return type(var) in types.__dict__.values() and not isinstance(var, types.InstanceType)
内置类型函数可能会有所帮助:
>>> a = 5
>>> type(a)
<type 'int'>
根据 S.Lott 的回答,你应该有这样的东西:
from simplejson import JSONEncoder
class JSONEncodeAll(JSONEncoder):
def default(self, obj):
try:
return JSONEncoder.default(self, obj)
except TypeError:
## optionally
# try:
# # you'd have to add this per object, but if an object wants to do something
# # special then it can do whatever it wants
# return obj.__json__()
# except AttributeError:
##
# ...do whatever you are doing now...
# (which should be creating an object simplejson understands)
使用:
>>> json = JSONEncodeAll()
>>> json.encode(myObject)
# whatever myObject looks like when it passes through your serialization code
这些调用将使用您的特殊类,如果 simplejson 可以处理它会处理的对象。否则你的包罗万象的功能将被触发,并且可能(取决于你是否使用可选部分)一个对象可以定义它自己的序列化
对我来说最好的选择是:
allowed_modules = set(['numpy'])
def isprimitive(value):
return not hasattr(value, '__dict__') or \
value.__class__.__module__ in allowed_modules
当 value 是一个模块并且value.__class__.__module__ == '__builtin__'
将失败时,此修复。
现在是 2020 年,我使用的是 python 3.7,现有的答案都不适合我。取而代之的是内置模块。就是这样:
import builtins
type(your_object).__name__ in dir(builtins)
该问题要求检查非类类型。这些类型没有__dict__
成员(您也可以测试__repr__
成员,而不是检查__dict__
)其他答案提到检查成员资格types.__dict__.values()
,但此列表中的某些类型是类。
def isnonclasstype(val):
return getattr(val,"__dict__", None) != None
a=2
print( isnonclasstype(a) )
a="aaa"
print( isnonclasstype(a) )
a=[1,2,3]
print( isnonclasstype(a) )
a={ "1": 1, "2" : 2 }
print( isnonclasstype(a) )
class Foo:
def __init__(self):
pass
a = Foo()
print( isnonclasstype(a) )
给我:
> python3 t.py
False
False
False
False
True
> python t.py
False
False
False
False
True