Skip to content

Instantly share code, notes, and snippets.

@domodomodomo
Last active June 6, 2018 02:47
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 domodomodomo/81088da7af8e71493c75caeea786b380 to your computer and use it in GitHub Desktop.
Save domodomodomo/81088da7af8e71493c75caeea786b380 to your computer and use it in GitHub Desktop.
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