繁体   English   中英

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

[英]Identifying that a variable is a new-style class in Python?

我正在使用Python 2.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中的所有内容都只是一个类,并且没有办法解决这个问题?

我想你要问的是:“我可以测试一个类是否在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 is_new_style_class(klass):
    return issubclass(klass, object)

def is_new_style_class_instance(instance):
    return issubclass(instance.__class__, object)

通常,您只需要is_new_style_class函数用于您的目的。 所有不是类都将抛出TypeError ,因此您可能希望将其更新为:

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 ,作为一个类型,根据定义是一个新式类(请参阅Python 2.2中的统一类型和类 ),或者 - 如果您愿意 - 新样式类是按定义类型。

并不是说“一切都是一个阶级”:你所碰到的是“一切都是一个对象 ”(也就是说,每一个(新式)事物都来自“对象”)。

但是新风格的类本身就是一种“类型”(实际上,引入它们是为了将类和类型结合在一起)。 所以你可以尝试检查

import types

type(o) == types.TypeType

这会解决你的问题吗?

检查旧式课程非常简单。 只需检查type(cls) is types.ClassType 检查新式类也很容易, isinstance(cls, type) 请注意,内置类型也是新式类。

似乎没有简单的方法来区分内置函数和用Python编写的类。 带有__slots__的新式类也没有__dict__,就像intstr 如果类metaclass重写__str__方法,则检查str(cls)是否与预期模式匹配失败。 其他一些方法也不起作用:

  • cls.__module__ == '__builtin__' (你可以在类上重新分配__module__)
  • not any(value is cls for value in vars(__builtins__).values()) (您可以向__builtin__模块添加内容)。

内置和用户定义类型的统一是如此之好以至于区分它们是非平凡的问题这一事实应该意味着你的基本观点。 你真的不应该区分它们。 如果它实现了预期的协议,那么对象是什么并不重要。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM