You could also do this using just the __init_subclass__ method. Create some class AddMixin, and use it like:

class _(AddMixin, using=mod.Cls):
    ...  

The AddMixin class is something like:

class AddMixin:
    def __init_subclass_(cls, *, using, **kwargs):
        super().__init_subclass__(**kwargs)
        using.__dict__.update(cls.__dict__)
        return None

This is probably buggy, but that's the general idea.

Not sure how people would feel about how this reads, but I think it's not too bad.

---
Ricky.

"I've never met a Kentucky man who wasn't either thinking about going home or actually going home." - Happy Chandler


On Thu, Jan 14, 2021 at 7:28 AM Paul Sokolovsky <pmiscml@gmail.com> wrote:
Hello,

On Thu, 14 Jan 2021 22:19:06 +1100
Steven D'Aprano <steve@pearwood.info> wrote:

> On Thu, Jan 14, 2021 at 02:05:50PM +0300, Paul Sokolovsky wrote:
>
> [...]
> > Semantically, Python can achieve the same with "imperative" syntax
> > like:
> >
> > def mixin_method(self, args):
> >     ...
> > Cls.mixin_method = mixin_method
> >
> >
> > The question then: what are the best practices in *declarative*
> > syntax to achieve the same effect in Python? (but of course, unlike
> > Ruby, there should be explicit syntactic marker that we augment
> > existing class, not redefine it). 
>
>     def Cls.mixin_method(self, args):
>         ...
>
> has been suggested as syntax for adding new methods to an existing
> class. I would use that occasionally.

Thanks for the info! But I'd say that I like syntax suggested by Chris
Angelico (which parallels Ruby's syntax) better. It reminds more of the
original class definition, and it's normal to add more than one
var/method via mixin/interface, so grouping them together using
"class ...:" makes sense. But "scoping" problems pops up nonetheless,
e.g. one would like, but really can't, do following:

import mod

@mixin
class mod.Cls:
    ...

So, here's the syntax I came to:

@mixin
class Cls(mod.Cls):
    ...

It literally reads like "let me add a mixin to class Cls
(specifically, mod.Cls)". IMHO, it's pretty neat. What do you think?

> Even more so, the generalisation:
>
>     def obj.method(self, args):
>         ...
>
> to add a method to any instance, not just to a class.

Nnnnooooo ;-). Instances can't have methods, only classes can.
Instances can only have instance variable storing a reference to a
method, which would need to be called (obj.method)(args), remember? ;-).

[]

--
Best regards,
 Paul                          mailto:pmiscml@gmail.com
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-leave@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/3C7R6DCCDQJRVBI5DG2NBMPNQ3XTB66B/
Code of Conduct: http://python.org/psf/codeofconduct/