如何识别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里一切都是类,根本没有其他选择?
4 个回答
1
并不是说“所有东西都是类”,你遇到的问题是“所有东西都是一个对象”(也就是说,每一个(新式的)东西都是从“对象”这个概念派生出来的)。
不过,新式类本身也是一种“类型”(实际上,它们的出现是为了将类和类型结合在一起)。所以你可以试着检查一下
import types
type(o) == types.TypeType
这样能解决你的问题吗?
2
我觉得这样就足够了:
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 中类型和类的统一),或者说,如果你愿意,新式类本质上就是类型。
8
我想你问的是:“我能否测试一个类是否在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 ')