Last active
January 30, 2016 09:23
-
-
Save DmitrySoshnikov/7fcc5b6acb2eefc345aa to your computer and use it in GitHub Desktop.
Delegation-based prototypes: implementing JavaScript semantics in Python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### | |
# Explicit delegation-based prototypes implementation. | |
# | |
# Implementing JavaScript semantics. | |
# | |
# Here we show that "delegation" is just a mechanism (a pattern) for | |
# implementation of the "inheritance" concept. In this specific case we | |
# have direct inheritance from objects, skipping the "class" step. | |
# | |
# See "OO Relationships" article for some details: | |
# https://medium.com/@DmitrySoshnikov/oo-relationships-5020163ab162 | |
# | |
# Note: Python itself is already delegation-based ;) | |
# | |
# by Dmitry Soshnikov <[email protected]> | |
# MIT Style License | |
## | |
# Because JS :P | |
undefined = None | |
# To bind a method at resolution | |
from functools import partial | |
class JSObject(object): | |
def __init__(self, props = None): | |
self.__props = props or {} | |
# Implement dynamic dispatch | |
def __getattr__(self, prop): | |
resolved = self.__props.get(prop) | |
# Resolved own prop. | |
if not resolved is None: | |
# In case if we resolved a function, bind | |
# it to needed context, making it a method. | |
if hasattr(resolved, '__call__'): | |
resolved = partial(resolved, self) | |
return resolved | |
# Else, lookup in the prototype chain via delegation. | |
__proto__ = self.__props.get('__proto__') | |
# Reached base inheritance link | |
if __proto__ is None: | |
return undefined | |
# Continue lookup. | |
return __proto__.__getattr__(prop) | |
foo = JSObject({'x': 10, 'getX': lambda self: self.x}) | |
bar = JSObject({'y': 20, '__proto__': foo}) | |
print(bar.x) # 10, inherited | |
print(bar.y) # 20, own | |
print(bar.getX()) # whoo-hoo! methods work too!, 10 | |
## | |
## Homework exercise: implement `set` and `delete` operations. | |
## |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'd just use kwargs: