簡體   English   中英

確定 Python 變量是否是內置類型的實例

[英]Determine if Python variable is an instance of a built-in type

我需要確定給定的 Python 變量是否是本機類型的實例: strintfloatboollistdict等等。 有沒有優雅的方法來做到這一點?

或者這是唯一的方法:

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 )。

實現此目的的最佳方法是將類型收集在一個名為primitiveTypes的元組列表中,並且:

if isinstance(myvar, primitiveTypes): ...

types模塊包含所有重要類型的集合,可以幫助構建列表/元組。

從 Python 2.2 開始工作

並不是說我知道您為什么要這樣做,因為 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)

通過這種方式,您可以輕松添加新的序列化程序,並且代碼易於維護和清除,因為每種類型都有自己的序列化程序。 請注意某些類型是內置的事實是如何變得完全無關緊要的。 :)

您似乎有興趣確保 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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM