Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prototypal programming in Python

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.

like image 465
Andrea Avatar asked Jan 07 '11 19:01

Andrea


People also ask

How is Python used for prototyping?

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.

Is Python good for rapid prototyping?

Python can be used for rapid prototyping, or for production-ready software development.

Does Python use prototype inheritance?

Prototype-based programming in Python. In prototype-based programming there is inheritance but no instantiation.

What is rapid prototyping in Python?

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.


2 Answers

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
like image 86
Lennart Regebro Avatar answered Sep 30 '22 02:09

Lennart Regebro


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.

like image 21
ffriend Avatar answered Sep 30 '22 02:09

ffriend