我可以使用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()
,而不是直接比较类型。