[Python-ideas] JavaScript-Style Object Creation in Python (using a constructor function instead of a class to create objects)

Chris Angelico rosuav at gmail.com
Sun May 14 08:45:24 EDT 2017


On Sun, May 14, 2017 at 9:14 PM, Steven D'Aprano <steve at pearwood.info> wrote:
>> There are a couple of
>> solutions to that, though. The easiest to implement would be to change the
>> first line to `self = subclass(ParentClass())` where the subclass function
>> looks at the next item in the call stack (i.e. `MyClass`) and makes it the
>> type of the object.
>
> You say this is the easiest to implement. Do you have an implementation?
> Does it work for CPython, Jython, IronPython, PyPy, Stackless, Nuitka,
> and other Python implementations? What of Python implementations that
> don't support intraspection of the call stack?
>
> (Perhaps we should just make that a required language feature. But
> that's a separate argument.)
>

Here's a much easier way to achieve that:

@Class
def MyClass(...):
    ...

As well as declaring that this is, in fact, a class (more reliable
than depending on a naming convention), this decorator could take the
return value from the original function and then tag it as a subclass
of that object, with the subclass's name being lifted from the
function's name. Something like:

def Class(func):
    @wraps(func)
    def wrapper(*a, **kw):
        ret = func(*a, **kw)
        if ret is None: return ret
        ret.__class__ = func.__name__ # pretend this works
        return ret
    return wrapper

This would chain, because "self = ParentClass()" will be going through
this decorator too. But honestly, I think I'd rather do something like
this:

def Class(func):
    class Thing:
        @wraps(func)
        def __new__(*a, **kw):
            func()
    Thing.__name__ = func.__name__
    return Thing

In other words, the transformation is to an actual class. The function
form becomes syntactic sugar for a particular form of class
definition. You could even do subclassing through the decorator:

def Class(*parents):
    def deco(func):
        class Thing(*parents):
    # etc

AFAIK all this is fully legal in current versions of Python 3. If you
want to mess around with classes and functions, decorators can do all
that and more, and IMO are the best way to prototype the syntax. No
changes needed to grammar or anything. It'll still be a class under
the hood, so isinstance checks will work, for instance (sorry,
couldn't resist). And it can all be done through a single entry point
that you can easily publish in a module on PyPI.

ChrisA


More information about the Python-ideas mailing list