简体   繁体   中英

isinstance(xxx, property) works, but what does that correspond to in the types module?

I can use isinstance to test if an attribute is a property (on the class actually), but I can't find anything in the types module that corresponds to a property.

Hopefully, the code below is going to make that more clear. All the other stuff I am testing does just fine to get a match.

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 "\n\nno match found... :(", to_test

the output...

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>]

what gives? why isn't the property recognized anywhere against the types?

The reason I am curious is that I have a debugging function that tries to pretty print complicated objects. I've learned a long time ago that calling methods on those objects is not a good idea. So I pass in a default list of the types of attributes not to look at.

li_skiptype=[types.MethodType]

Almost all the time, I will skip methods, but I can pretty print them, if I remove them from this list. It'd be nice to add and make my skipping of property types conditional as well.

And well... I am just plain curious why they are not in types.

types is not meant to be a comprehensive collection of all Python object types. From the module documentation :

This module defines names for some object types that are used by the standard Python interpreter, but not for the types defined by various extension modules.

Emphasis mine.

The majority of objects in the module are just aliases for the built-in types, see the module source code ; there isn't anything magical about the type objects here; they are just more Python objects, some of which are not easily exposed otherwise. The module is then just a convenience.

You already have the property object to test against, you don't need a reference to that object in the types module too.

In Python 3, the types module has been further scaled back to a limited set of types that might otherwise be hard to get a reference to. The types that have been removed are those that are readily available directly as built-ins. Again, quoting from the Python 2 documentation:

Starting in Python 2.2, built-in factory functions such as int() and str() are also names for the corresponding types. This is now the preferred way to access the type instead of using the types module.

Since property was added to the language as a built-in from the get-go, there never was a need to expose it in types as you have direct access to it already.

Note that it is almost always better to use isinstance() , and allow for subclasses. If you must constrain a test to one type only, use is as types a singletons; use type(obj) is sometype rather than type(obj) == sometype . Also see the Python styleguide :

Object type comparisons should always use isinstance() instead of comparing types directly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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