In this guide, you'll explore Python's types module, which provides names for built-in type objects. Learn its features and examples for dynamic programming.
The types
module in Python defines names for various object types that are used internally by the interpreter. This module is particularly useful when you need to perform type checking or create new types dynamically.
Table of Contents
- Introduction
- Key Classes and Types
MappingProxyType
SimpleNamespace
DynamicClassAttribute
GeneratorType
CoroutineType
AsyncGeneratorType
CodeType
FunctionType
LambdaType
MethodType
BuiltinFunctionType
BuiltinMethodType
ModuleType
- Examples
- Using
MappingProxyType
- Using
SimpleNamespace
- Using
DynamicClassAttribute
- Using
- Real-World Use Case
- Conclusion
- References
Introduction
The types
module provides a standard interface for type-related operations. It includes definitions for many of the types that the Python interpreter uses internally, making it useful for type checking and dynamic type creation.
Key Classes and Types
MappingProxyType
A wrapper for read-only dictionaries.
from types import MappingProxyType
writable = {'key1': 'value1'}
read_only = MappingProxyType(writable)
print(read_only['key1'])
# read_only['key1'] = 'new_value' # This will raise a TypeError
Output:
value1
SimpleNamespace
A simple object subclass that provides attribute access to its namespace.
from types import SimpleNamespace
ns = SimpleNamespace(x=10, y=20)
print(ns.x, ns.y)
ns.z = 30
print(ns.z)
Output:
10 20
30
DynamicClassAttribute
An attribute to support computed attributes in extension types.
from types import DynamicClassAttribute
class MyClass:
def __init__(self, value):
self._value = value
@DynamicClassAttribute
def value(self):
return self._value
obj = MyClass(10)
print(obj.value)
Output:
10
GeneratorType
The type of generator-iterator objects, such as those created by generator functions.
from types import GeneratorType
def generator():
yield 1
yield 2
gen = generator()
print(isinstance(gen, GeneratorType))
Output:
True
CoroutineType
The type of coroutine objects, such as those created by async functions.
from types import CoroutineType
async def coroutine():
await asyncio.sleep(1)
coro = coroutine()
print(isinstance(coro, CoroutineType))
Output:
True
sys:1: RuntimeWarning: coroutine 'coroutine' was never awaited
AsyncGeneratorType
The type of asynchronous generator objects.
from types import AsyncGeneratorType
async def async_generator():
yield 1
yield 2
agen = async_generator()
print(isinstance(agen, AsyncGeneratorType))
Output:
True
CodeType
The type for code objects, such as those returned by compile()
.
from types import CodeType
code = compile('print("Hello, World!")', '<string>', 'exec')
print(isinstance(code, CodeType))
Output:
True
FunctionType
The type for user-defined functions.
from types import FunctionType
def func():
pass
print(isinstance(func, FunctionType))
Output:
True
LambdaType
The type for lambda functions. It is the same as FunctionType
.
from types import LambdaType
lambda_func = lambda x: x
print(isinstance(lambda_func, LambdaType))
Output:
True
MethodType
The type for bound and unbound methods of class instances.
from types import MethodType
class MyClass:
def method(self):
pass
obj = MyClass()
print(isinstance(obj.method, MethodType))
Output:
True
BuiltinFunctionType
The type for built-in functions.
from types import BuiltinFunctionType
print(isinstance(len, BuiltinFunctionType))
Output:
True
BuiltinMethodType
The type for built-in methods of classes.
from types import BuiltinMethodType
print(isinstance([].append, BuiltinMethodType))
Output:
True
ModuleType
The type for modules.
import types
import sys
print(isinstance(sys, types.ModuleType))
Output:
True
Examples
Using MappingProxyType
from types import MappingProxyType
writable = {'key1': 'value1'}
read_only = MappingProxyType(writable)
print(read_only['key1']) # Outputs: value1
writable['key1'] = 'new_value'
print(read_only['key1']) # Outputs: new_value
try:
read_only['key1'] = 'another_value' # Raises TypeError
except TypeError as e:
print(e)
Output:
value1
new_value
'mappingproxy' object does not support item assignment
Using SimpleNamespace
from types import SimpleNamespace
ns = SimpleNamespace(a=1, b=2)
print(ns.a, ns.b) # Outputs: 1 2
ns.c = 3
print(ns.c) # Outputs: 3
print(ns) # Outputs: namespace(a=1, b=2, c=3)
Output:
1 2
3
namespace(a=1, b=2, c=3)
Using DynamicClassAttribute
from types import DynamicClassAttribute
class MyClass:
def __init__(self, value):
self._value = value
@DynamicClassAttribute
def value(self):
return self._value
obj = MyClass(10)
print(obj.value) # Outputs: 10
Output:
10
Real-World Use Case
Creating Dynamic Types
The types
module can be used to create dynamic types at runtime, which is useful for metaprogramming and frameworks that need to generate classes dynamically.
import types
def make_class(name, base_classes, attrs):
return types.new_class(name, base_classes, exec_body=lambda ns: ns.update(attrs))
attrs = {'x': 1, 'y': 2, 'method': lambda self: self.x + self.y}
NewClass = make_class('NewClass', (object,), attrs)
instance = NewClass()
print(instance.method()) # Outputs: 3
Output:
3
Conclusion
The types
module in Python provides a variety of type definitions that are useful for type checking and dynamic type creation. It supports a wide range of types used internally by the Python interpreter, making it used for advanced programming tasks.
Comments
Post a Comment
Leave Comment