Created
March 14, 2018 23:08
-
-
Save Fuyukai/90c1ea8e294bfae1dd2f93dc48eca03b to your computer and use it in GitHub Desktop.
Python, without classes.
This file contains 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
def _suspend_self(namespace, suspended): | |
""" | |
Suspends a function, so that it has a self. | |
:param namespace: The self namespace to use. | |
:return: A function that will call the next function with self. | |
""" | |
def suspender(*args, **kwargs): | |
return suspended(namespace, *args, **kwargs) | |
suspender.__name__ = suspended.__name__ | |
suspender.__defaults__ = suspended.__defaults__ | |
suspender.__signature__ = getattr(suspended, "__signature__", None) | |
return suspender | |
def make_class(locals: dict): | |
""" | |
Makes a class, from the locals of the callee. | |
:param locals: The locals to build the class from. | |
""" | |
# try and find a `__call__` to implement the call function | |
# this is made as a function so that namespace and called can refer to eachother | |
def call_maker(): | |
if '__call__' in locals and callable(locals['__call__']): | |
return _suspend_self(namespace, locals['__call__']) | |
def _not_callable(*args, **kwargs): | |
raise TypeError('This is not callable') | |
return _not_callable | |
# this acts as the "self" object | |
# all attributes are set on this | |
def namespace(): | |
return called() | |
# get the callable function that namespace delegates to | |
# this is called afterwards so that call_maker has the chance to load namespace from cellvars | |
called = call_maker() | |
# make an init substitute function | |
def new_class(*args, **kwargs): | |
init = locals.get("__init__") | |
if init is not None: | |
init(namespace, *args, **kwargs) | |
return namespace | |
# update namespace | |
for name, item in locals.items(): | |
if callable(item): | |
fn = _suspend_self(namespace, item) | |
setattr(namespace, name, fn) | |
return new_class | |
def make(fn): | |
""" | |
Makes a class from a function. Example usage: | |
.. code-block:: python | |
from noclasses import make_class, make | |
@make | |
def MyClass(): | |
def __init__(self, first, second): | |
self.first = first | |
self.second = second | |
def add(self): | |
return self.first + self.second | |
return make_class(locals()) | |
instance = MyClass(2, 2) | |
print(instance.add()) # 4 | |
""" | |
return fn() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is invalid. You assign attributes directly to the class, not to instances. Example: