Visitor

0.1.3 · maintenance · verified Tue Apr 14

Visitor is a tiny Python library designed to facilitate the implementation of the visitor design pattern. It provides a base `Visitor` class to help separate algorithms from the object structures they operate on, addressing the peculiarities of dynamic typing in Python for this pattern. The library is very small, and its documentation suggests that users might consider copying the source code directly into their projects. The current version is 0.1.3, with the last release dating back to 2016, indicating a very mature or inactive maintenance cadence.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to use the `Visitor` class to implement a simple JSON encoder. It defines a `JSONEncoder` class that inherits from `Visitor` and provides `visit_` methods for different Python types (list, dict, str, int, float). The `generic_visit` method acts as a fallback for unhandled types.

from visitor import Visitor

class JSONEncoder(Visitor):
    def __init__(self):
        self.output = []

    def visit_list(self, obj):
        self.output.append('[')
        for item in obj:
            self.visit(item)
            self.output.append(',')
        if len(obj) > 0: # Remove trailing comma if list is not empty
            self.output.pop()
        self.output.append(']')

    def visit_dict(self, obj):
        self.output.append('{')
        for key, value in obj.items():
            self.visit(key)
            self.output.append(':')
            self.visit(value)
            self.output.append(',')
        if len(obj) > 0: # Remove trailing comma if dict is not empty
            self.output.pop()
        self.output.append('}')

    def visit_str(self, obj):
        self.output.append(f'"{obj}"')

    def visit_int(self, obj):
        self.output.append(str(obj))

    def visit_float(self, obj):
        self.output.append(str(obj))

    def generic_visit(self, obj):
        # Fallback for types not explicitly handled, e.g., None, bool
        self.output.append(str(obj).lower() if isinstance(obj, bool) else 'null' if obj is None else repr(obj))

    def encode(self, obj):
        self.output = []
        self.visit(obj)
        return ''.join(self.output)


# Example Usage:
data = {
    'name': 'Alice',
    'age': 30,
    'isStudent': False,
    'courses': ['Math', 'Science'],
    'address': {'city': 'New York', 'zip': 10001},
    'grades': [95, 88.5, 76],
    'null_field': None
}

encoder = JSONEncoder()
json_string = encoder.encode(data)
print(json_string)

expected_output = '{"name":"Alice","age":30,"isStudent":false,"courses":["Math","Science"],"address":{"city":"New York","zip":10001},"grades":[95,88.5,76],"null_field":null}'
assert json_string == expected_output
print("Output matches expected JSON.")

view raw JSON →