Zope Component Architecture
zope.component, along with zope.interface, provides a robust component architecture for Python, enabling the definition, registration, and lookup of loosely coupled components such as adapters and utilities. It is a core part of the Zope Toolkit project. The current version is 7.1. New minor versions are released roughly every 2-6 months, and major versions every 2-3 years, following semantic versioning.
Warnings
- breaking Backwards compatibility imports from `zope.component.interfaces`, `zope.component.registry`, and the entire `zope.component.hookable` module were removed.
- breaking Dropped support for older Python versions, requiring Python 3.7+ (for 6.1+), Python 3.10+ (for 7.1+).
- breaking Replaced `pkg_resources` namespace with PEP 420 native namespace.
- gotcha The declaration-order of interfaces being adapted to is important for adapter lookup. It must be the same as the order of parameters given to the adapter and used to query the adapter.
Install
-
pip install zope.component
Imports
- getUtility
from zope.component import getUtility
- provideUtility
from zope.component import provideUtility
- queryUtility
from zope.component import queryUtility
- IComponent
from zope.interface.interfaces import IComponent
- ComponentRegistry
from zope.interface.registry import ComponentRegistry
Quickstart
from zope.interface import Interface, implementer
from zope.component import provideUtility, getUtility, queryUtility, ComponentLookupError
# 1. Define an Interface
class IGreeter(Interface):
"""The Greeter interface provides a greeting method."""
def greet(name: str) -> str:
"""Say hello to the given name."""
# 2. Implement the Interface
@implementer(IGreeter)
class HelloGreeter:
"""A simple greeter component."""
def greet(self, name: str) -> str:
return f"Hello, {name}!"
# 3. Register the Utility
# A utility is a component looked up by an interface and an optional name.
# We can register an instance of the Greeter.
my_greeter_instance = HelloGreeter()
provideUtility(my_greeter_instance, IGreeter, name='default-greeter')
# You can also register without a name for a singleton utility for the interface
provideUtility(HelloGreeter(), IGreeter) # No name, becomes default for IGreeter
# 4. Look up and use the Utility
# Using getUtility (raises ComponentLookupError if not found)
try:
default_greeter = getUtility(IGreeter)
print(f"Default greeting: {default_greeter.greet('World')}")
except ComponentLookupError:
print("Default greeter not found.")
try:
named_greeter = getUtility(IGreeter, name='default-greeter')
print(f"Named greeting: {named_greeter.greet('Alice')}")
except ComponentLookupError:
print("Named greeter not found.")
# Using queryUtility (returns None if not found, or a default value if specified)
missing_greeter = queryUtility(IGreeter, name='non-existent')
print(f"Querying missing greeter (should be None): {missing_greeter}")
fallback_greeter = queryUtility(IGreeter, name='non-existent', default='Fallback')
print(f"Querying with fallback: {fallback_greeter}")