Javascript uses a prototype-based model for its objects. Nevertheless, the language is very flexible, and it is easy to write in a few lines functions which replace other kind on constructs. For instance, one can make a class
function, emulating the standard class behaviour, including inheritance or private members. Or one can mimcìic functional tools by writing, for instance, a curry
function which will take a function and some of its arguments and return the partially applied function.
I was wondering whether it is possible to do the reverse and imitate the prototypal method in more classical languages. In particular I have been thinking a bit whether it is possible to imitate prototypes in Python, but the lack of support for anonymous functions (more general than lambdas) leaves me stuck.
Is it possible to write some functions to mimic propotypes in class-based languages, in particular in Python?
EDIT Let me give some example of how one could go implementing such a thing (but I'm not really able to do it all).
First, the thing which most closely resembles Javascript objects is a Python dictionary. So we could have simple objects like
foo = {
'bar': 1,
'foobar': 2
}
Of course we want to add method, and this is not a problem as long as the method fits in a lambda
foo = {
'bar': 1,
'foobar': 2,
'method': lambda x: x**2
}
So now we can call for instance
foo['method'](2)
>>> 4
Now if we had arbitrary functions as methods we could go on like this. First we need the functions inside foo
to have access to foo
itself; otherwise they are just ordinary functions and not methods.
I guess one could do this by applying a makeObject
function to foo
, which loops through foo
values and, whenever finds a value that is callable, modifies its __call__
attribute to pass foo
as its first argument.
At this stage we would have self standing objects, which can be declared without the need of creating classes.
Then we need to be able to give foo
a prototype, which can be passed as a second argument of the makeObject
function. The function should modify foo.__getattr__
and foo.__setattr__
as follows: whenever the attribute is not found in foo
, it should be searched in foo.prototype
.
So, I think I would be able to implement this, expect for one thing: I cannot think any ways to declare methods more complicated than lambdas, except for declaring them beforehand and attaching them to my object. The problem is the lack of anonymous functions. I asked here because maybe some Python guru could find some clever way to circumvent this.
Python is a great language for prototyping testing and debugging tools: In Python, dynamic analysis and static analysis are extremely easy to implement. Python provides an enormous infrastructure for parsing, handling programs as trees, and constraint solving.
Python can be used for rapid prototyping, or for production-ready software development.
Prototype-based programming in Python. In prototype-based programming there is inheritance but no instantiation.
Rapid Prototyping is an iterative process used to visualize what a website or an application will look like in order to get feedback and validation from users, stakeholders, developers, and designers.
It's much easier in Python than in JS. Your JS code could be replaced with this in Python:
>>> class Foo(object):
... pass
>>> foo = Foo()
>>> foo.bar = 1
>>> foo.foobar = 2
Then you can add methods dynamically as well
>>> foo.method = lambda x: x**2
>>> foo.method(2)
4
For methods more complicated than lambdas, you declare them as functions, and they will have access to foo itself, no problems:
>>> def mymethod(self, bar, foobar):
... self.bar = bar
... self.foobar = foobar
>>> foo.mymethod = mymethod
>>> foo.mymethod(1,2)
>>> foo.bar
1
>>> foo.foobar
2
Or for that matter:
>>> mymethod(foo, 3, 4)
>>> foo.bar
3
>>> foo.foobar
4
Same thing.
So as you see, doing what your example is in Python is almost ridiculously simple. The question is why. :) I mean, this would be better:
>>> class Foo(object):
... def __init__(self, bar, foobar):
... self.bar = bar
... self.foobar = foobar
... def method(self, x):
... return x**2
Each time you read some property of Python object, method __getattribute__
is called, so you can overload it and completely control access to object's attributes. Nevertheless, for your task a bit different function - __getattr__
- may be used. In contrast to __getattribute__
it is called only if normal lookup for an attribute failed, i.e. at the same time, as prototype lookup in JavaScript starts. Here's usage:
...
def __getattr__(self, name):
if hasattr(prototype, name)
return getattr(prototype, name)
else:
raise AttributeError
Also pay attention to this question, since it has some notes on old and new style objects.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With