3 ms·
Most of these use cases are idiomatically handled by data descriptors and/or metaclasses, though the typing could reduce boilerplate.
by marmaduke 8y ago
Most of these use cases are idiomatically handled by data descriptors and/or metaclasses, though the typing could reduce boilerplate.
- mlthoughts2018 8y agoI came to say this as well. The flexibility of Python’s data model generally means that in a lot of cases where you’d want a macro in another language or costly reflection, you can just dynamically create a function or class (with type()), dynamically change things to be properties (by calling the property decorator as a function), mess with how isinstance and issubclass work if you want interface enforcement, etc. I do agree macros could reduce boilerplate though, but add the extra complexity that someone has to understand AST transformations instead of just regular old Python type dynamic code. Stepping back though, whether with macros or metaprogramming in the dynamic data model, the hugest rule of thumb is: don’t do this stuff. You aren’t going to need it. Don’t solve your problem (like arg parsing in the Rust example) with code gen. Always just write a bit of unmysterious extra boilerplate code that your colleagues of mixed skill will thank you for. That verbose thing that is easier for a wide audience to quickly grok despite uglier code with more boilerplate, that is great software, with mature design decision making. It will live a lot longer and be way easier to incrementally modify than the esoteric code gen approach.
- marmaduke 8y agoI agree with your last point. Even though data descriptors are available I still nowadays prefer plain old attributes
- ben509 8y ago> I do agree macros could reduce boilerplate though, but add the extra complexity that someone has to understand AST transformations instead of just regular old Python type dynamic code. Not only do you have to understand AST transformations, but you also have mysterious stack traces pointing to non-existent code. The amount of tooling to make it debuggable and understandable is significant; the Javascript folks have done that lift but that's a large community that was heavily dependent on it. All that said, I think AST transforms have their uses. I wrote a library[1] for pyrsistent to allow normal mutable usage of pyrsistent's immutable data structures. But I think that works because the interface it presents and the behavior it's modeling is ordinary python. [1]: https://pypi.org/project/pyrsistent-mutable/ https://pypi.org/project/pyrsistent-mutable/