Skip to content

Instantly share code, notes, and snippets.

@p7g
Last active October 3, 2019 12:36
Show Gist options
  • Save p7g/a813de640194e7d080d6b1b42f5717d9 to your computer and use it in GitHub Desktop.
Save p7g/a813de640194e7d080d6b1b42f5717d9 to your computer and use it in GitHub Desktop.
A little object system written in Python, inspired by https://www.aosabook.org/en/500L/a-simple-object-model.html
class Type:
def __init__(self, name, *, method_table=None, parent=None):
self.name = name
self.method_table = method_table or {}
self.parent = parent
def resolve_method(self, name, /):
if name in self.method_table:
return self.method_table[name]
elif self.parent is not None:
return self.parent.resolve_method(name)
return None
TYPE = Type('type')
class Method:
def __init__(self, function, /):
self.function = function
def call(self, instance, /, args, kwargs):
return self.function(instance, *args, **kwargs)
method = Method
@method
def typeof(instance):
return instance.base.name
Object = Type('Object', method_table={'typeof': typeof}, parent=TYPE)
class Instance:
def __init__(self, base, args=(), kwargs=None):
kwargs = kwargs or {}
self.base = base
self.fields = {}
if init := self.base.resolve_method('__init__'):
init.call(self, args, kwargs)
def call_method(self, name, /, args=(), kwargs=None):
kwargs = kwargs or {}
if method := self.base.resolve_method(name):
return method.call(self, args, kwargs)
raise AttributeError(name)
def getattr(self, name, /):
if name in self.fields:
return self.fields[name]
raise AttributeError(name)
def setattr(self, name, value, /):
self.fields[name] = value
def delattr(self, name):
if name in self.fields:
del self.fields[name]
return True
return False
@method
def get_name(self):
return self.getattr('name')
@method
def set_name(self, name, /):
return self.setattr('name', name)
@method
def Test_init(self, name):
self.setattr('name', name)
Test = Type('Test', method_table={
'get_name': get_name,
'set_name': set_name,
'__init__': Test_init,
}, parent=Object)
test = Instance(Test, kwargs={'name': 'hullo'})
print('get_name:', test.call_method('get_name'))
print('typeof:', test.call_method('typeof'))
print('set_name', test.call_method('set_name', args=('world',)))
print('get_name:', test.call_method('get_name'))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment