Description & What I've tried:
I have seen many posts in stackoverflow about binding methods to class instances (I'm aware there are bunch of duplicates already).
However I havent found a discussion referring to binding a method to the class itself. I can think of workarounds but I'm curious if there is a simple way to achieve following:
import types
def quacks(some_class):
def quack(self, number_of_quacks):
self.number_of_quacks = number_of_quacks
setattr(some_class, "quack", types.MethodType(quack, some_class))
return some_class
@quacks
class Duck:
pass
but above would not work:
d1 = Duck()
d2 = Duck()
d1.quack(1)
d2.quack(2)
print(d2.number_of_quacks)
# 2
print(d1.number_of_quacks)
# 2
because quack is actually modifying the class itself rather than the instance.
There are two workarounds I can think of. Either something like below:
class Duck:
def __init__(self):
setattr(self, "quack", types.MethodType(quack, self))
or something like
class Quacks:
def quack(self, number_of_quacks):
self.number_of_quacks = number_of_quacks
class Duck(Quacks):
pass
Question:
So my question is, is there a simple way to achieve the simple @quacks
class decorator I described above?
Why I'm asking: I intend to create a set of functions to modularly add common methods I use to classes. If I dont quit this project, the list is likely to grow over time and I would prefer to have it look nice on code definition. And as a matter of taste, I think option 1 below looks nicer than option 2:
# option 1
@quacks
@walks
@has_wings
@is_white
@stuff
class Duck:
pass
# option 2
class Duck(
Quacks,
Walks,
HasWings,
IsWhite,
Stuff):
pass