[Python-ideas] Multiple arguments for decorators
Andrew Barnert
abarnert at yahoo.com
Tue Dec 1 04:01:05 EST 2015
On Nov 30, 2015, at 21:28, Kevin Modzelewski <kmod at dropbox.com> wrote:
>
> Hmm I could have done a bit better with my example. class defs can work with any callable as a "metaclass", so creating an actual metaclass was overkill:
>
> def property_wrapper(name, bases, attrs):
> return property(attrs.get('get'), attrs.get('set'), attrs.get('del'), attrs.get('__doc__'))
>
> class Foo(object):
> class myprop(metaclass=property_wrapper):
> def get(self):
> return 1
> def set(self, v):
> pass
> __doc__ = 1
But even this is still more complicated than just changing the property type's initializer to take a class instead of a bunch of functions (that is, making property a normal class decorator instead of making it a weird multiple-function decorator and then writing a separate wrapper that lets you pass a class as if it were a normal class decorator)?
And again, what's the benefit from this extra complexity? Unless you have a whole lot of decorators written that all need this exact same transformation, you're just abstracting out an arbitrary part of the logic that doesn't seem to fit any natural grain.
> I wasn't suggesting it for performance reasons, just that there's already an API for "call a function with the locals defined in this scope" that we can use directly, rather than using a different wrapper of the underlying API (aka class creation). But I think from a readability standpoint it's much nicer to wrap a normal classdef with a "@make_property" decorator rather than doing it via a metaclasss. I think this could be different if there was a simpler way to use a metaclass (especially, a way that wasn't so class-related). Here's an example of what it could look like:
>
> scope(property_wrapper) myprop:
> def get(self):
> return 1
That's still a lot less readable than this:
@property
class myprop:
def get(self):
return 1
> The thing that's nice is that "scope(X) Y" can be just a simple transformation to "class Y(metaclass=X)". Anyway, I'm not trying to seriously suggest this as the way to go, but just trying to say that if you want to apply a function to the locals defined in a scope, that feature already exists even if it is ugly to use :)
>
>
>> On Mon, Nov 30, 2015 at 8:37 PM, Andrew Barnert <abarnert at yahoo.com> wrote:
>> On Nov 30, 2015, at 19:21, Kevin Modzelewski via Python-ideas <python-ideas at python.org> wrote:
>> >
>> > Class scopes definitely feel like a good match -- they are a way of saying "evaluate all of these expression, pass the resulting locals to a custom function, and bind the result of that function to the classname". Usually the function is type(), which constructs a new class, but by setting a custom metaclass we can avoid creating a class just to wrap the scope:
>>
>> Is there really a harm in creating a class?
>>
>> A property is a type, and the obvious way to simulate it in Python rather than C (as shown by the sample code in the HOWTO) is with a class statement.
>>
>> Besides, if you're creating many thousands of properties in a loop, the time and space cost of property creation is probably the least of your worries.
>>
>> Again, maybe that isn't true for other types of decorators this feature might be useful for, but without having any examples to think about, it's hard to guess...
>>
>> > class PropertyMetaclass(type):
>> > def __new__(cls, name, bases, attrs):
>> > return property(attrs.get('get'), attrs.get('set'), attrs.get('del'), attrs.get('__doc__'))
>>
>> I still don't get the benefit of having a metaclass or constructor function or wrapper function or anything else, instead of just making property take a class instead of four functions. The latter is significantly nicer on the user side, and only a tiny bit more verbose in the implementation of property, and easier to understand. Unless there are other decorators where they wouldn't be true, or so many potentially useful one-shot decorators that defining them all a little more succinctly is worth the cost, why add the extra layer?
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20151201/8b86dfab/attachment-0001.html>
More information about the Python-ideas
mailing list