Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Emulating Object Oriented Programming with dict and function.
"""Emulating Object Oriented Programming with dict and function.
### 0. reference
1) This code was written by refering below content.
Python のクラスシステム - http://www.shido.info/py/python7.html
### 1. emulating 3 concepts, class, instance and method.
1) class -> dict
2) instance -> dict
3) method -> function
### 2. emulating 3 built-in functions.
1) setattr -> setattr_
2) getattr -> getattr_
3) type -> type_
https://docs.python.jp/3/library/functions.html#type
https://docs.python.jp/3/library/functions.html#setattr
https://docs.python.jp/3/library/functions.html#getattr
### 3. creating 1 new function for convinience.
1) instantiate -> instantiate_
### 4. consideration
The complexity of getattr_() function in this code shows
that attribue reference is one of the most important factor
in object oriented programming language.
"""
#
#
#
def main():
print('### 0. You have got two same results.')
print()
print('### 1. instance object')
print(' executing with builtin functions')
sample_code(setattr, getattr, type, instantiate)
print()
print('### 2. emulating dict object')
print(' executing with emulating functions')
sample_code(setattr_, getattr_, type_, instantiate_)
print()
#
#
#
def sample_code(setattr, getattr, type, instantiate):
#
# 1. Define class.
#
def __init__(self, name, task):
setattr(self, 'name', name)
setattr(self, 'task', task)
def work(self, hour):
name = getattr(self, 'name')
task = getattr(self, 'task')
max_hour = getattr(self, 'max_hour')
return '%s %s for %d hours of %d hours.'\
% (name, task, hour, max_hour)
ItWorker = type(
'ItWorker',
(object, ),
{'max_hour': 7, '__init__': __init__, 'work': work}
)
#
# 2. Instantiate object.
#
henley = instantiate(ItWorker, 'Henley', 'makes web site')
thomas = instantiate(ItWorker, 'Thomas', task='checks up server')
gates = instantiate(ItWorker, name='Gates', task='writes programs')
#
# 3.
#
print('# (1) Refer instance attributes.')
print(getattr(henley, 'max_hour'))
print(getattr(thomas, 'name'))
print(getattr(gates, 'task'))
print('# (2) Overwrite instance attributes.')
setattr(henley, 'max_hour', 12)
setattr(thomas, 'name', 'James')
setattr(gates, 'task', 'desings web page')
print(getattr(henley, 'max_hour'))
print(getattr(thomas, 'name'))
print(getattr(gates, 'task'))
print('# (3) Refer class attributes.')
# print(getattr(henley, 'max_hour')) # class attribute was overwritten.
print(getattr(thomas, 'max_hour'))
print(getattr(gates, 'max_hour'))
print('# (4) Call methods.')
print(getattr(henley, 'work')(3))
print(getattr(thomas, 'work')(4))
print(getattr(gates, 'work')(6))
print('# (5) Change methods dynamically.')
def holiday(self, days):
name = getattr(self, 'name')
return '%s enjoys vacation for %d days' % (name, days)
setattr(ItWorker, 'work', holiday)
print(getattr(henley, 'work')(3))
print(getattr(thomas, 'work')(4))
print(getattr(gates, 'work')(6))
def instantiate(cls, *args, **kwargs):
self = cls(*args, **kwargs)
return self
#
# Using dict and function(closure),
# we can emulate instance object, class object and method.
#
def setattr_(obj: dict, attr_name, value):
"""Set a value to the attribute."""
obj[attr_name] = value
def getattr_(obj: dict, attr_name):
"""Get a value from the attribute."""
# instance attribute
if attr_name in obj:
value = obj[attr_name]
return value
# class attribute
elif attr_name in obj['__class__']:
value = obj['__class__'][attr_name]
# value
if not callable(value):
return value
# method
else:
def method(*args, **kwargs):
return value(obj, *args, **kwargs)
return method
else:
raise AttributeError("object has no attribute '%s'" % attr_name)
def type_(name: str, bases: tuple, class_name_space: dict) -> dict:
"""Create a new class object."""
cls = {}
cls['__name__'] = name
cls['__bases__'] = bases # inheritance is not implemented.
cls.update(class_name_space)
return cls
def instantiate_(cls: dict, *args, **kwargs) -> dict:
"""Create a new instance object."""
self = {}
self['__class__'] = cls
getattr_(self, '__init__')(*args, **kwargs)
return self
#
#
#
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.