Isinstance (xxx, property)可以工作,但是在types模块中它对应什么呢?



我可以使用isinstance来测试属性是否为属性(实际上是在类上),但我在types模块中找不到任何与属性对应的内容。

希望下面的代码将使这一点更清楚。我正在测试的所有其他东西都可以很好地获得匹配。

class MyClass(object):
    def __init__(self):
        self._counter = 0
    def counter():
        doc = "The counter property."
        def fget(self):
            self._counter +=1
            return self._counter
        return locals()
    counter = property(**counter())
    def bar(self):
        self

foo = MyClass()
print "foo.counter", foo.counter
print "foo.counter", foo.counter

print "this will be an int. type(foo.counter):", type(foo.counter)

print "but the class knows it's  a property isinstance(foo.__class__.counter, property):", isinstance(foo.__class__.counter, property)

#let's see if we can determine the type of a given item...
import types
to_test = [3, foo.__class__.counter, foo.bar, {}]
print "matches against types:"
for k, v in vars(types).items():
    for test in to_test[:]:
        if type(test) == v:
            #flag a match, remove it from tests
            print ("  %s is a %s" % (test, v))
            to_test.remove(test)
#what's left over?  the property
print "nnno match found... :(", to_test

输出……

foo.counter 1
foo.counter 2
this will be an int. type(foo.counter): <type 'int'>
but the class knows its  a property isinstance(foo.__class__.counter, property): True
matches against types:
  3 is a <type 'int'>
  <bound method MyClass.bar of <__main__.MyClass object at 0x106b06a50>> is a <type 'instancemethod'>
  {} is a <type 'dict'>

no match found... :( [<property object at 0x106afc838>]

给了什么?为什么属性在任何地方都不能被类型识别?

我好奇的原因是我有一个调试函数,它试图打印复杂的对象。很久以前我就知道在这些对象上调用方法不是一个好主意。所以我传入了一个默认的属性类型列表。

li_skiptype=[types.MethodType]

几乎所有时候,我会跳过方法,但如果我从这个列表中删除它们,我可以很好地打印它们。添加并使我跳过属性类型也是有条件的,这将是很好的。

,…我只是很好奇为什么它们不在类型中

types并不意味着是所有Python对象类型的综合集合。来自模块文档:

该模块定义了一些对象类型的名称,这些类型由标准Python解释器使用,但不包括各种扩展模块定义的类型。

我特别强调。

模块中的大多数对象只是内置类型的别名,请参阅模块源代码;这里的类型对象没有什么神奇之处;它们只是更多的Python对象,其中一些不容易公开。模块只是为了方便。

您已经有了要测试的property对象,您不需要在types模块中也引用该对象。

在Python 3中,types模块已进一步缩减为一组有限的类型,否则可能很难获得引用。已经删除的类型是那些可以直接作为内置的类型。再次引用Python 2文档中的内容:

从Python 2.2开始,内置工厂函数(如int()str())也是相应类型的名称。这是现在访问类型的首选方式,而不是使用types模块。

由于property从一开始就作为内置的添加到语言中,所以从来没有必要在types中公开它,因为您已经可以直接访问它。

请注意,使用isinstance()几乎总是更好,并允许子类。如果你必须约束一个测试只有一个类型,使用is作为一个单例类型;使用type(obj) is sometype而不是type(obj) == sometype。参见Python样式指南:

对象类型比较应该始终使用isinstance(),而不是直接比较类型。

最新更新