Identifying that a variable is a new-style class in Python?
我使用的是python 2.x,我想知道是否有一种方法来判断变量是否是一个新的样式类?我知道如果这是一个老式的课程,我可以做以下的事情来了解。
1 2 3 4 5 6 7 8 9 10 11 | 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' |
但我还没有找到适合新课程的东西。我发现了这个问题,但所提出的解决方案似乎没有如预期的那样有效,因为简单的值被标识为类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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代码中被定义为一个新的样式类吗?".技术上简单的类型,如
这是一些有用的东西,尽管它有点像黑客:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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的输出:
1 2 3 | False True False |
以下是另一种方法:
1 2 | def is_new_style(cls): return str(cls).startswith('<class ') |
我相信这就足够了:
1 2 3 4 5 | def is_new_style_class(klass): return issubclass(klass, object) def is_new_style_class_instance(instance): return issubclass(instance.__class__, object) |
通常情况下,您只需要
1 2 3 4 5 | def is_new_style_class(klass): try: return issubclass(klass, object) except TypeError: return False |
实例:
1 2 3 4 5 6 7 8 9 10 11 12 | >>> 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 |
不是"一切都是一个阶级":你遇到的是"一切都是一个对象"(即,每一个(新风格)的事物都是从"对象"下降的)。
但是新样式的类本身就是一个"类型"(实际上,它们是为了将类和类型结合在一起而引入的)。所以你可以试着检查
1 2 3 | import types type(o) == types.TypeType |
那能解决你的问题吗?
检查旧样式的类真的很容易。只需检查
似乎没有什么简单的方法来区分内置的和用Python编写的类。带有槽的新样式类也没有槽,就像
cls.__module__ == '__builtin__' (您可以在类上重新分配模块)not any(value is cls for value in vars(__builtins__).values()) (您可以向内置模块添加内容)。
内置类型和用户定义类型的统一性是如此之好,以至于区分它们是一个非常重要的问题,这对您来说应该意味着基础点。你真的不应该区分它们。如果对象实现了预期的协议,那么对象是什么并不重要。