Skip to content

Instantly share code, notes, and snippets.

@mhlr
Last active December 26, 2020 06:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mhlr/1479e0c1b366a787323d to your computer and use it in GitHub Desktop.
Save mhlr/1479e0c1b366a787323d to your computer and use it in GitHub Desktop.
Enabling delegation / prototypal inheritance / instance based programming in Python
from proto import Proto, ProtoMeta
__metaclass__ = ProtoMeta
class A:
x = "This is X"
def getY(self):
return self._y
class B:
_y = "This is Y"
if __name__ == "__main__":
a = A(None)
b = B(a)
print b.x
print b.getY()
from proto import Proto, ProtoMeta
class A(Proto):
x = "This is X"
def getY(self):
return self._y
class B(Proto):
_y = "This is Y"
class C(object):
def __getattr__(self, name):
return "So you want "+name
class D(B,C):
pass
if __name__ == "__main__":
a = A(None)
b = B(a)
print b.x
print b.getY()
d = D(a)
print d.x
print d.getY()
print d.z
import types
import inspect
class Proto(object):
def __new__(self, proto, *args, **kw):
return super(Proto, self).__new__(self, *args, **kw)
def __init__(self, proto, *args, **kw):
self.proto = proto
super(Proto, self).__init__(*args, **kw)
def __getattr__(self, name):
try:
attr = getattr(self.proto, name)
if (inspect.ismethod(attr) and attr.__self__ is self.proto):
attr = types.MethodType(attr.__func__, self)
return attr
except AttributeError:
return super(Proto, self).__getattr__(name)
class ProtoMeta(type):
def __new__(self, name, bases, dict):
return super(ProtoMeta, self).__new__(self, name, (Proto,) + bases, dict)
def __init__(self, name, bases, dict):
super(ProtoMeta, self).__init__(name, (Proto,) + bases, dict)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment