- Terminology
- Object Identity and Type
- Reference Counting and Garbage Collection
- References and Copies
- First-Class Objects
- Built-in Types for Representing Data
- Built-in Types for Representing Program Structure
- Built-in Types for Interpreter Internals
- Object Behavior and Special Methods
Built-in Types for Representing Program Structure
In Python, functions, classes, and modules are all objects that can be manipulated as data. Table 3.9 shows types that are used to represent various elements of a program itself.
Table 3.9 Built-in Python Types for Program Structure
Type Category |
Type Name |
Description |
Callable |
types.BuiltinFunctionType |
Built-in function or method |
type |
Type of built-in types and classes |
|
object |
Ancestor of all types and classes |
|
types.FunctionType |
User-defined function |
|
types.MethodType |
Class method |
|
Modules |
types.ModuleType |
Module |
Classes |
object |
Ancestor of all types and classes |
Types |
type |
Type of built-in types and classes |
Note that object and type appear twice in Table 3.9 because classes and types are both callable as a function.
Callable Types
Callable types represent objects that support the function call operation. There are several flavors of objects with this property, including user-defined functions, built-in functions, instance methods, and classes.
User-Defined Functions
User-defined functions are callable objects created at the module level by using the def statement or with the lambda operator. Here’s an example:
def foo(x,y): return x + y bar = lambda x,y: x + y
A user-defined function f has the following attributes:
Attribute(s) |
Description |
f.__doc__ |
Documentation string |
f.__name__ |
Function name |
f.__dict__ |
Dictionary containing function attributes |
f.__code__ |
Byte-compiled code |
f.__defaults__ |
Tuple containing the default arguments |
f.__globals__ |
Dictionary defining the global namespace |
f.__closure__ |
Tuple containing data related to nested scopes |
In older versions of Python 2, many of the preceding attributes had names such as func_code, func_defaults, and so on. The attribute names listed are compatible with Python 2.6 and Python 3.
Methods
Methods are functions that are defined inside a class definition. There are three common types of methods—instance methods, class methods, and static methods:
class Foo(object): def instance_method(self,arg): statements @classmethod def class_method(cls,arg): statements @staticmethod def static_method(arg): statements
An instance method is a method that operates on an instance belonging to a given class. The instance is passed to the method as the first argument, which is called self by convention. A class method operates on the class itself as an object. The class object is passed to a class method in the first argument, cls. A static method is a just a function that happens to be packaged inside a class. It does not receive an instance or a class object as a first argument.
Both instance and class methods are represented by a special object of type types.MethodType. However, understanding this special type requires a careful understanding of how object attribute lookup (.) works. The process of looking something up on an object (.) is always a separate operation from that of making a function call. When you invoke a method, both operations occur, but as distinct steps. This example illustrates the process of invoking f.instance_method(arg) on an instance of Foo in the preceding listing:
f = Foo() # Create an instance meth = f.instance_method # Lookup the method and notice the lack of () meth(37) # Now call the method
In this example, meth is known as a bound method. A bound method is a callable object that wraps both a function (the method) and an associated instance. When you call a bound method, the instance is passed to the method as the first parameter (self). Thus, meth in the example can be viewed as a method call that is primed and ready to go but which has not been invoked using the function call operator ().
Method lookup can also occur on the class itself. For example:
umeth = Foo.instance_method # Lookup instance_method on Foo umeth(f,37) # Call it, but explicitly supply self
In this example, umeth is known as an unbound method. An unbound method is a callable object that wraps the method function, but which expects an instance of the proper type to be passed as the first argument. In the example, we have passed f, a an instance of Foo, as the first argument. If you pass the wrong kind of object, you get a TypeError. For example:
>>> umeth("hello",5) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: descriptor 'instance_method' requires a 'Foo' object but received a 'str' >>>
For user-defined classes, bound and unbound methods are both represented as an object of type types.MethodType, which is nothing more than a thin wrapper around an ordinary function object. The following attributes are defined for method objects:
Attribute |
Description |
m.__doc__ |
Documentation string |
m.__name__ |
Method name |
m.__class__ |
Class in which this method was defined |
m.__func__ |
Function object implementing the method |
m.__self__ |
Instance associated with the method (None if unbound) |
One subtle feature of Python 3 is that unbound methods are no longer wrapped by a types.MethodType object. If you access Foo.instance_method as shown in earlier examples, you simply obtain the raw function object that implements the method. Moreover, you’ll find that there is no longer any type checking on the self parameter.
Built-in Functions and Methods
The object types.BuiltinFunctionType is used to represent functions and methods implemented in C and C++. The following attributes are available for built-in methods:
Attribute |
Description |
b.__doc__ |
Documentation string |
b.__name__ |
Function/method name |
b.__self__ |
Instance associated with the method (if bound) |
For built-in functions such as len(), __self__ is set to None, indicating that the function isn’t bound to any specific object. For built-in methods such as x.append, where x is a list object, __self__ is set to x.
Classes and Instances as Callables
Class objects and instances also operate as callable objects. A class object is created by the class statement and is called as a function in order to create new instances. In this case, the arguments to the function are passed to the __init__() method of the class in order to initialize the newly created instance. An instance can emulate a function if it defines a special method, __call__(). If this method is defined for an instance, x, then x(args) invokes the method x.__call__(args).
Classes, Types, and Instances
When you define a class, the class definition normally produces an object of type type. Here’s an example:
>>> class Foo(object): ... pass ... >>> type(Foo) <type 'type'>
The following table shows commonly used attributes of a type object t:
Attribute |
Description |
t.__doc__ |
Documentation string |
t.__name__ |
Class name |
t.__bases__ |
Tuple of base classes |
t.__dict__ |
Dictionary holding class methods and variables |
t.__module__ |
Module name in which the class is defined |
t.__abstractmethods__ |
Set of abstract method names (may be undefined if there aren’t any) |
When an object instance is created, the type of the instance is the class that defined it. Here’s an example:
>>> f = Foo() >>> type(f) <class '__main__.Foo'>
The following table shows special attributes of an instance i:
Attribute |
Description |
i.__class__ |
Class to which the instance belongs |
i.__dict__ |
Dictionary holding instance data |
The __dict__ attribute is normally where all of the data associated with an instance is stored. When you make assignments such as i.attr = value, the value is stored here. However, if a user-defined class uses __slots__, a more efficient internal representation is used and instances will not have a __dict__ attribute. More details on objects and the organization of the Python object system can be found in Chapter 7.
Modules
The module type is a container that holds objects loaded with the import statement. When the statement import foo appears in a program, for example, the name foo is assigned to the corresponding module object. Modules define a namespace that’s implemented using a dictionary accessible in the attribute __dict__. Whenever an attribute of a module is referenced (using the dot operator), it’s translated into a dictionary lookup. For example, m.x is equivalent to m.__dict__["x"]. Likewise, assignment to an attribute such as m.x = y is equivalent to m.__dict__["x"] = y. The following attributes are available:
Attribute |
Description |
m.__dict__ |
Dictionary associated with the module |
m.__doc__ |
Module documentation string |
m.__name__ |
Name of the module |
m.__file__ |
File from which the module was loaded |
m.__path__ |
Fully qualified package name, only defined when the module object refers to a package |