如何用Python标准库更简洁实现Django模板可访问的属性式单元格读取?
Nice solution you've got there already! It gets the job done, but we can definitely trim down the boilerplate using Python's standard library tools. Let's look at a couple of cleaner approaches:
1. Dynamic Inline Class (Minimal Boilerplate)
Instead of defining a separate CellReader class, we can create it dynamically inline with the type() function. This keeps all the logic contained within the cell property without losing functionality:
class Row(object): _cells = {'first_name': 'James', 'last_name': 'Charland'} def get_cell(self, name): return self._cells[name] @property def cell(self): # Create a dynamic proxy class that forwards attribute calls to get_cell return type('', (object,), { '__init__': lambda self, row: setattr(self, 'row', row), '__getattr__': lambda self, name: self.row.get_cell(name) })(self)
2. Leverage types.SimpleNamespace for Cleaner Initialization
If you want a bit more readability (and avoid writing a custom __init__), use types.SimpleNamespace from the standard library. It handles attribute initialization out of the box, so we just need to add our __getattr__ logic:
from types import SimpleNamespace class Row(object): _cells = {'first_name': 'James', 'last_name': 'Charland'} def get_cell(self, name): return self._cells[name] @property def cell(self): class CellReader(SimpleNamespace): def __getattr__(self, name): return self.row.get_cell(name) return CellReader(row=self)
How These Work
Both approaches rely on Python's __getattr__ magic method, which triggers whenever an attribute isn't found on an object. We use this to forward any attribute access on the cell proxy (like row.cell.first_name) directly to the parent Row's get_cell method.
Your original implementation is perfectly valid—these are just ways to cut down on unnecessary code using tools already built into Python, no external packages required.
内容的提问来源于stack exchange,提问作者Jieter

