确定变量是Python中的一个新型类?

确定变量是Python中的一个新型类?,python,class,python-2.x,Python,Class,Python 2.x,我正在使用Python2.x,我想知道是否有一种方法可以判断一个变量是否是一个新样式的类?我知道,如果这是一个老式的课程,我可以做下面的事情来找出答案 import types class oldclass: pass def test(): o = oldclass() if type(o) is types.InstanceType: print 'Is old-style' else: print 'Is NOT old-style' 但是我还没有找到

我正在使用Python2.x,我想知道是否有一种方法可以判断一个变量是否是一个新样式的类?我知道,如果这是一个老式的课程,我可以做下面的事情来找出答案

import types

class oldclass:
  pass

def test():
  o = oldclass()
  if type(o) is types.InstanceType:
    print 'Is old-style'
  else:
    print 'Is NOT old-style'
但是我还没有找到任何适用于新型类的东西。我发现了,但建议的解决方案似乎并不像预期的那样有效,因为简单的值被标识为类

import inspect

def newclass(object):
  pass

def test():
  n = newclass()
  if inspect.isclass(n):
    print 'Is class'
  else:
    print 'Is NOT class'
  if inspect.isclass(type(n)):
    print 'Is class'
  else:
    print 'Is NOT class'
  if inspect.isclass(type(1)):
    print 'Is class'
  else:
    print 'Is NOT class'
  if isinstance(n, object):
    print 'Is class'
  else:
    print 'Is NOT class'
  if isinstance(1, object):
    print 'Is class'
  else:
    print 'Is NOT class'
那么,有没有办法做这样的事情呢?或者说Python中的所有东西都只是一个类,没有办法绕过它?

这并不是说“所有东西都是一个类”:你碰到的是“所有东西都是一个对象”(也就是说,所有(新样式)东西都是从“对象”派生而来的)

但是新型类本身就是一种“类型”(实际上,引入新类是为了将类和类型结合在一起)。所以你可以试试看

import types

type(o) == types.TypeType

这解决了您的问题吗?

我想您要问的是:“我可以测试一个类是否在Python代码中定义为一个新样式的类吗?”。技术上简单的类型,例如
int
是新样式的类,但是仍然可以区分用Python编写的类和内置类型

下面是一些有效的方法,尽管有点像黑客:

def is_new_style(cls):
    return hasattr(cls, '__class__') \
           and \
           ('__dict__' in dir(cls) or hasattr(cls, '__slots__'))


class new_style(object):
    pass

class old_style():
    pass

print is_new_style(int)
print is_new_style(new_style)
print is_new_style(old_style)
Python 2.6的输出:

False
True
False
这里有一种不同的方法:

def is_new_style(cls):
    return str(cls).startswith('<class ')
def是新样式(cls):

return str(cls).startswith('我相信这就足够了:

def is_new_style_class(klass):
    return issubclass(klass, object)

def is_new_style_class_instance(instance):
    return issubclass(instance.__class__, object)
通常,出于您的目的,您只需要使用
is\u new\u style\u class
函数。非类的所有内容都会抛出
类型错误,因此您可能希望将其更新为:

def is_new_style_class(klass):
    try:
        return issubclass(klass, object)
    except TypeError:
        return False
示例:

>>> class New(object): pass
... 
>>> is_new_style_class(New)
True
>>> class Old: pass
... 
>>> is_new_style_class(Old)
False
>>> is_new_style_class(1)
False
>>> is_new_style_class(int)
True

int
,作为一个类型,根据定义是一个新的样式类(请参阅),或者——如果您愿意的话——新样式类是根据定义类型。

检查旧样式类非常容易。只需检查
type(cls)是类型。ClassType
。检查新样式类也很容易,
isinstance(cls,type)
。请注意,内置类型也是新样式的类

似乎没有简单的方法来区分内置类和用Python编写的类。带有uuu插槽的新样式类也没有uu dict,就像
int
str
一样。检查str(cls)是否如果类元类重写_str__方法,则匹配预期模式失败。其他一些方法也不起作用:

  • cls.\uuuuu模块
    (您可以在类上重新分配模块)
  • 不是任何(值是变量中值的cls(\uuuu内置)。values())
    (您可以将内容添加到\uu内置模块)


内置类型和用户定义类型的统一非常好,区分它们是一个非常重要的问题,这一事实应该向您暗示了这一点。您真的不必区分它们。如果实现了预期的协议,对象是什么并不重要。

对于int也返回True否,表达式对于旧样式类和新样式类,n的计算结果均为false。但是,对于新样式类,而不是旧样式类,n的计算结果均为true:type(n.。\uuuuu class\uuu)= Type。Type,但它也对“It”这样的基本类型求值,所以它不是我所要找的。正确的是,int是一个新类的一个实例。这是统一的一个点。但是一个int没有一个Dave Johansen属性,我假设所有的类都有。@假设。我正在处理一个递归序列化其子类的类,我希望能够判断该子类是否是一个类,并通过递归序列化其子类来处理它。您之前的评论似乎应该是实际问题,而原始问题看起来像一个(可能是错误的)您为解决问题所采取的步骤。请勾选此项:您可能希望给我们一个示例,说明一个类有另一个类作为子类;另外,请确保您不是在谈论实例。一个实例有要序列化的子实例更常见。很抱歉,因为我指的是实例,而不是类Itself.另外,根据~unutbu的响应,可以使用来识别旧样式类:def is_old_style(cls):return not hasattr(cls,'init')对于错误信息,很抱歉,但是如果旧样式类具有显式定义的_init_方法,但是type(cls),则上述is_old_style(cls)不起作用丹尼尔是第一个版本的<代码> iSyNeXyType 需要改进:它不会被认为是新类型的类:<代码>类NeXType(对象):,
@thettΖΖΖΖΖΥ,谢谢你抓住了这一点。我已经更新了代码来处理这种情况。这两种方法看起来都很粗糙,但我也找不到更好的方法来实现这一点。在这两种方法之间,我倾向于第二种方法的简单性。问题是所有东西(即使是老式类和基本类型,如int)将返回true。您的注释的问题是:旧样式类返回False,
int
(定义为类型)是新样式类。问题是int没有_dict_uu属性,因此违反了其中一个“规则”新样式的类。@Dave:但这是你的一个规则还是一个误解?这是一个新样式的类:
class NewStyle(object):\uu slots\uu=“attribute”,
及其实例没有
dict属性。实例测试不正确:作为
对象
并不意味着拥有一个新样式的类。例如:标准
HTMLParser
模块的代码显示
HTMLParser.HTMLParser
是一个旧样式的类;但是,
是一个新样式的类ance(HTMLParser())
错误地返回True。
types.ClassType
为,使此答案过时。此外,在CPython下有一种区分内置类和用户定义类的方法。