Introduction: A package xy
defines a Node
class (names are not real). Multiple nodes create a graph-like structure that the package does interesting things with. Basic example:
node0 = xy.Node(... some arguments here ...)
Nodes can have optional features. This is currently implemented with add-on/mix-in classes. Something like that:
class NodeF7(xy.Feature7, xy.Node):
pass
node1 = NodeF7(..., feature7_timeout=5)
isinstance(node1, xy.Feature7)
test is true.Problem: Very often it is necessary to define a new class just to create a single instance of it. I'm thinking about simplifiyng the usage to just:
node1 = xy.Node(..., feature7_timeout=5)
ie when the Node
class encounters any feature7
related parameter, it should automatically include the Feature7
class add-on. It is important, that isinstance(node1, xy.Feature7)
becomes true.
I would like to ask how to implement that in the package. Is there a design pattern for this?
__new__
function?First, we prepare a way to register features.
feature_registry = {}
def register_feature(*parameters):
def decorator(cls):
for parameter in parameters:
feature_registry[parameter] = cls
return cls
return decorator
@register_feature('feature7_timeout')
class Feature7:
def __init__(self, *args, feature7_timeout=None, **kwargs):
print('feature7_timeout:', feature7_timeout)
def feature7(self):
assert isinstance(self, Feature7)
Then, in the __new__
function, we get the feature classes and create a new type.
class Node:
def __new__(cls, *args, **kwargs):
feature_classes = {feature_registry.get(k) for k in kwargs}
feature_classes.discard(None)
cls = type(cls.__name__, (*feature_classes, cls), {})
return super().__new__(cls)
Usage:
node1 = Node(feature7_timeout=5)
node1.feature7()
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.