Section 13.12. Built-in Functions for Classes, Instances, and Other Objects


13.12. Built-in Functions for Classes, Instances, and Other Objects

13.12.1. issubclass()

The issubclass() Boolean function determines if one class is a subclass or descendant of another class. It has the following syntax:

    issubclass(sub, sup)


issubclass() returns TRue if the given subclass sub is indeed a subclass of the superclass sup (and False otherwise). This function allows for an "improper" subclass, meaning that a class is viewed as a subclass of itself, so the function returns true if sub is either the same class as sup or derived from sup. (A "proper" subclass is strictly a derived subclass of a class.)

Beginning with Python 2.3, the second argument of issubclass() can be tuple of possible parent classes for which it will return true if the first argument is a subclass of any of the candidate classes in the given tuple.

13.12.2. isinstance()

The isinstance() Boolean function is useful for determining if an object is an instance of a given class. It has the following syntax:

    isinstance(obj1, obj2)


isinstance() returns TRue if obj1 is an instance of class obj2 or is an instance of a subclass of obj2 (and False otherwise), as indicated in the following examples:

    >>> class C1(object): pass     ...     >>> class C2(object): pass     ...     >>> c1 = C1()     >>> c2 = C2()     >>> isinstance(c1, C1)     True     >>> isinstance(c2, C1)     False     >>> isinstance(c1, C2)     False     >>> isinstance(c2, C2)     True     >>> isinstance(C2, c2)     Traceback (innermost last):       File "<stdin>", line 1, in ?         isinstance(C2, c2)     TypeError: second argument must be a class


Note that the second argument should be a class; otherwise, you get a TypeError. The only exception is if the second argument is a type object. This is allowed because you can also use isinstance() to check if an object obj1 is of the type obj2, i.e.,

   >>> isinstance(4, int)    True    >>> isinstance(4, str)    False    >>> isinstance('4', str)    True


If you are coming from Java, you may be aware of the warning against using its equivalent, instanceof(), due to performance reasons. A call to Python's isinstance() will not have the same performance hit primarily because it only needs it to perform a quick search up the class hierarchy to determine what classes it is an instance of, and even more importantly, it is written in C!

Like issubclass(), isinstance() can also take a tuple as its second argument. This feature was added in Python 2.2. It will return TRue if the first argument is an instance of any of the candidate types and classes in the given tuple. Also be sure to read more about isinstance() in Section 13.16.1 on page 595.

13.12.3. hasattr(), getattr(), setattr(), delattr()

The *attr() functions can work with all kinds of objects, not just classes and instances. However, since they are most often used with those objects, we present them here. One thing that might throw you off is that when using these functions, you pass in the object you are working on as the first argument, but the attribute name, the second argument to these functions, is the string name of the attribute. In other words, when operating with obj.attr, the function call will be like *attr(obj, 'attr'...)this will be clear in the examples that follow.

The hasattr() function is Boolean and its only purpose is to determine whether or not an object has a particular attribute, presumably used as a check before actually trying to access that attribute. The getattr() and setattr() functions retrieve and assign values to object attributes, respectively. getattr() will raise an AttributeError exception if you attempt to read an object that does not have the requested attribute, unless a third, optional default argument is given. setattr() will either add a new attribute to the object or replace a pre-existing one. The delattr() function removes an attribute from an object.

Here are some examples using all the *attr() BIFs:

    >>> class myClass(object):     ...     def __init__(self):     ...         self.foo = 100     ...     >>> myInst = myClass()     >>> hasattr(myInst, 'foo')     True     >>> getattr(myInst, 'foo')     100     >>> hasattr(myInst, 'bar')     False     >>> getattr(myInst, 'bar')     Traceback (most recent call last):       File "<stdin>", line 1, in ?         getattr(myInst, 'bar')     AttributeError: myClass instance has no attribute 'bar'     >>> getattr(c, 'bar', 'oops!')     'oops!'     >>> setattr(myInst, 'bar', 'my attr')     >>> dir(myInst)     ['__doc__', '__module__', 'bar', 'foo']     >>> getattr(myInst, 'bar')    # same as myInst.bar     'my attr'     >>> delattr(myInst, 'foo')     >>> dir(myInst)     ['__doc__', '__module__', 'bar']     >>> hasattr(myInst, 'foo')     False


13.12.4. dir()

We first experienced dir() in Exercises 2-12, 2-13, and 4-7. In those exercises, we used dir() to give us information about all the attributes of a module. We now know that dir() can be applied to objects as well.

In Python 2.2, dir() received a significant upgrade. Because of these changes, the voluntarily implemented __members__ and __methods__ data attributes have been deprecated. dir() provides more details than the old one. According to the documentation, "In addition to the names of instance variables and regular methods, it also shows the methods that are normally invoked through special notations, like __iadd__ (+=), __len__ (len()), __ne__ (!=)." Here are more specifics from the Python documentation:

  • dir() on an instance (classic or new-style) shows the instance variables as well as the methods and class attributes defined by the instance's class and all its base classes.

  • dir() on a class (classic or new-style) shows the contents of the __dict__ of the class and all its base classes. It does not show class attributes that are defined by a metaclass.

  • dir() on a module shows the contents of the module's __dict__. (This is unchanged.)

  • dir() without arguments shows the caller's local variables. (Again, unchanged.)

  • There are more details; in particular, for objects that override __dict__ or __class__, these are honored, and for backwards compatibility, __members__ and __methods__ are honored if they are defined.

13.12.5. super()

The super() function was added in 2.2 for new-style classes. The purpose of this function is to help the programmer chase down the appropriate superclass with which the proper method can be invoked. In simple cases, the programmer will likely just call the ancestor class method in an unbound fashion. Using super() simplifies the task of search for a suitable ancestor and passes in the instance or type object on your behalf when you call it.

In Section 13.11.4, we described the method resolution order (MRO) that is used to chase down attributes in ancestor classes. For each class defined, an attribute named __mro__ is created as a tuple that lists the classes that need to be searched, in the order they are searched. Here is its syntax:

    super(type[, obj])


Given type, super() "returns the superclass" of type. You may also pass in obj, which should be of the type type if you want the superclass to be bound, otherwise it will be unbound. The obj argument can also be a type, but it needs to be a subclass of type. In summary, when obj is given:

  • If obj is an instance, then isinstance(obj, type) must be true

  • If obj is a class or type, then issubclass(obj, type) must be TRue

Actually, super() is a factory function that makes a super object that uses the __mro__ attribute for a given class to find the appropriate superclass. Most notably, it searches that MRO starting from the point where the current class is found. For more details, again please see Guido van Rossum's essay on type and class unification, where he even gives a pure Python implementation of super() so you can get a better idea of how it works!

Final thought... super()'s primary use is in the lookup of a superclass attribute, e.g., super(MyClass, self).__init__(). If you are not performing such a lookup, you probably do not need to be using super().

There are various examples how to use super() scattered throughout this chapter. Also be sure to read the important notes about super() in Section 13.11.2, especially the Core Note in that section.

13.12.6. vars()

The vars() built-in function is similar to dir() except that any object given as the argument must have a __dict__ attribute. vars() will return a dictionary of the attributes (keys) and values of the given object based on the values in its __dict__ attribute. If the object provided does not have such an attribute, an TypeError exception is raised. If no object is provided as an argument to vars(), it will display the dictionary of attributes (keys) and the values of the local namespace, i.e., locals(). We present an example of calling vars() with a class instance:

class C(object):      pass >>> c = C() >>> c.foo = 100 >>> c.bar = 'Python' >>> c.__dict__ {'foo': 100, 'bar': 'Python'} >>> vars(c) {'foo': 100, 'bar': 'Python'}


Table 13.3 summarizes the built-in functions for classes and class instances.

Table 13.3. Built-in Functions for Classes, Instances, and Other Objects

Built-in Function

Description

issubclass(sub, sup)

Returns true if class sub is a subclass of class sup, False otherwise

isinstance(obj1, obj2)

Returns true if instance obj1 is an instance of class obj2 or is an instance of a subclass of obj2; will also return TRue if obj1 is of type obj2; otherwise it returns False

hasattr(obj, attr)

Returns TRue if obj has attribute attr (given as a string), False otherwise

getattr(obj, attr[, default])

Retrieves attribute attr of obj; same as return obj.attr; if attr is not an attribute of obj, default returned if given; else AttributeError exception raised

setattr(obj, attr, val)

Sets attribute attr of obj to value val, over riding any previously existing attribute value; otherwise, attribute is created; same as obj.attr = val

delattr(obj, attr)

Removes attribute attr (given as a string) from obj; same as del obj.attr

dir(obj=None)

Returns a list of the attributes of obj; if obj not given, dir() displays local namespace attributes, i.e., locals().keys()

super(type, obj=None)[a]

Returns a proxy object representing the super class of type; if obj is not passed in, the super object returned is unbound; otherwise if obj is a type issubclass(obj, type) must be TRue; otherwise isinstance(obj, type) must be TRue

vars(obj=None)

Returns a dictionary of the attributes and values of obj; if obj not given, vars() displays local namespace dictionary (attributes and values), i.e., locals()


[a] New in Python 2.2; only works with new-style classes.



Core Python Programming
Core Python Programming (2nd Edition)
ISBN: 0132269937
EAN: 2147483647
Year: 2004
Pages: 334
Authors: Wesley J Chun

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net