str
、int
、float
、bool
、list
、dict
等等。有没有更优雅的方法来完成它?或者这是唯一的方法:
if myvar in (str, int, float, bool):
# do something
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
的一个实例(即AnyClass.__class__
是type
)。
__builtins__
。 - niekasbuiltins
。 - Mikaelblomkvistssonobj
是一个类而不是一个实例? - jtlz2builtin_module_name=dict().__class__.__module__
。 - MichaelMoser虽然我不知道为什么你想这样做,因为在Python中没有任何“简单”的类型,它们都是对象。但是这个方法是可行的:
type(theobject).__name__ in dir(__builtins__)
但是明确列出类型可能更好,因为这样更清晰。或者更好的方法是:改变应用程序,使您不需要知道差异。
更新:需要解决的问题是如何为对象(甚至内置对象)制作序列化器。最好的方法不是制作一个大而臃肿的序列化器将内置对象与其他对象区别对待,而是根据类型查找序列化器。
类似于这样:
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
的元组列表中:
if isinstance(myvar, primitiveTypes): ...
types
模块包含了许多重要的类型,可以帮助构建列表/元组。
types
模块并没有提供完整的类型列表。例如其中没有 int
。但是有 builtins
模块提供了大部分内置类型,因此可以使用 builtin_types = tuple(getattr(builtins, t) for t in dir(builtins) if isinstance(getattr(builtins, t), type))
来获取内置类型列表,并使用 isinstance(value, builtin_types)
进行判断。 - Bakuriuisinstance
对于内置类型的子类返回 True,而 type(value) in (bool, str, int, float, tuple, list, dict)
仅对内置类型的实例返回 True。这个差异在这个答案中指出:https://dev59.com/e2w15IYBdhLWcg3wzO1_#6392016 - 0 _您似乎对确保simplejson能够处理您的类型感兴趣。这可以通过简单地进行以下操作来完成:
try:
json.dumps( object )
except TypeError:
print "Can't convert", object
现在是2020年,我正在使用Python 3.7版本,但是现有的解答都无法解决我的问题。相反,builtins模块可以解决我的问题。下面是解决方法:
import builtins
type(your_object).__name__ in dir(builtins)
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)
对我来说,最好的选择是:
allowed_modules = set(['numpy'])
def isprimitive(value):
return not hasattr(value, '__dict__') or \
value.__class__.__module__ in allowed_modules
当值为模块且value.__class__.__module__ == '__builtin__'
时,此修复将失败。
__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
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可以处理对象,则会使用它。否则,将触发您的万能功能,并且可能(取决于是否使用可选部分)对象可以定义自己的序列化。