Определите, является ли переменная Python экземпляром встроенного типа - PullRequest
19 голосов
/ 24 августа 2009

Мне нужно определить, является ли данная переменная Python экземпляром собственного типа: str, int, float, bool, list, dict и так далее. Есть ли элегантный способ сделать это?

Или это единственный способ:

if myvar in (str, int, float, bool):
    # do something

Ответы [ 9 ]

14 голосов
/ 24 августа 2009

Лучший способ добиться этого - собрать типы в список кортежей с именами primitiveTypes и:

if isinstance(myvar, primitiveTypes): ...

Модуль types содержит коллекции всех важных типов, которые могут помочь в создании списка / кортежа.

Работает с Python 2.2

8 голосов
/ 22 июля 2013

Это старый вопрос, но, похоже, ни один из ответов на самом деле не отвечает на конкретный вопрос: «(Как) Определить, является ли переменная Python экземпляром встроенного типа». Обратите внимание, что это не «[...] определенного / заданного встроенного типа», но a .

Правильный способ определить, является ли данный объект экземпляром встроенного типа / класса , состоит в том, чтобы проверить, определен ли тип объекта в модуле __builtin__.

def is_builtin_class_instance(obj):
    return obj.__class__.__module__ == '__builtin__'

Предупреждение: если obj является классом, а не экземпляром, независимо от того, является ли этот класс встроенным или нет, будет возвращено значение True, поскольку класс также является объектом, экземпляром type (т.е. AnyClass.__class__ - это type).

8 голосов
/ 24 августа 2009

Не знаю, почему вы захотите это сделать, поскольку в 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)

Таким образом, вы можете легко добавлять новые сериализаторы, а код легко поддерживать и очищать, поскольку каждый тип имеет свой собственный сериализатор. Обратите внимание, как тот факт, что некоторые типы встроены, стал совершенно неактуальным. :)

7 голосов
/ 24 августа 2009

Вы, похоже, заинтересованы в том, чтобы simplejson обрабатывал ваши типы. Это делается тривиально

try:
    json.dumps( object )
except TypeError:
    print "Can't convert", object

Что надежнее, чем пытаться угадать, какие типы обрабатывает реализация JSON.

2 голосов
/ 24 августа 2009

Что такое «нативный тип» в Python? Пожалуйста, не основывайте свой код на типах, используйте Duck Typing .

1 голос
/ 26 марта 2015

Вы можете получить доступ ко всем этим типам с помощью types модуля:

`builtin_types = [ i for i in  types.__dict__.values() if isinstance(i, type)]`

в качестве напоминания, модуль импорта types первый

def isBuiltinTypes(var):
    return type(var) in [i for i in  types.__dict__.values() if isinstance(i, type)] and not isinstance(var, types.InstanceType)
1 голос
/ 24 августа 2009

Встроенная функция типа может быть полезна:

>>> a = 5
>>> type(a)
<type 'int'>
0 голосов
/ 26 сентября 2017

Для меня лучший вариант:

allowed_modules = set(['numpy'])
def isprimitive(value):
  return not hasattr(value, '__dict__') or \
  value.__class__.__module__ in allowed_modules

Это исправление, когда значение является модулем, а value.__class__.__module__ == '__builtin__' завершится ошибкой.

0 голосов
/ 25 августа 2009

исходя из ответа С. Лотта, вы должны иметь что-то вроде этого:


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 сможет позаботиться об объекте, он это сделает. В противном случае ваши функциональные возможности будут активированы, и, возможно, (в зависимости от того, используете ли вы необязательную часть) объект может определить свою собственную сериализацию

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...