From: Thomas Jollans on
On 07/15/2010 08:45 PM, Karsten Wutzke wrote:
> On 15 Jul., 20:28, Thomas Jollans <tho...(a)jollans.com> wrote:
>> On 07/15/2010 07:58 PM, Karsten Wutzke wrote:
>>
>>> Hello,
>>
>>> this is obviously a Python OO question:
>>
>>> Since Python isn't stringly typed,
>>
>> I expect this is an innocent typo, and you mean strictly.
>>
>>> single-dispatch isn't available per se. So is the "double-dispatch" Visitor pattern,
>>
>
> Yes, typo, I meant strictly.
>
>> Wait, what?
>> First of all, python is strictly typed in that every object has exactly
>> one type, which is different from other types. So you can't do "1"+2, as
>> you can in some other languages.
>>
>> Anyway, this is interesting: Tell me more about how Python's dynamic
>> nature makes it impossible to do whatever you're trying to do. I'm
>> baffled. What are you trying to do, anyway?
>>
>>> which is usually used
>>> in OO systems to implement code generators. So, what is the de facto
>>> method in Python to handle source code generation?
>>
>> WHOA! Now if that isn't a Gedankensprung. Also, I'm still very far from
>> your train of thought, apparently: Now, the thing that code generators
>> probably share is that they write code to files. It depends on what I'm
>> trying to do of course, but I expect there's a good chance that if I
>> wrote a code generator in Python, it wouldn't be particularly
>> object-oriented at all.
>
> Well, I'm most experienced in OO, so writing OO in Python seems like
> the way to start with Python. The visitor pattern uses single-
> dispatch, that is, it determines which method to call be the type of
> object passed in. I did some reading and it turned out that Python
> can't do it without some tricks (function decorators and 3rd party
> code).

Well, yes: the name of a function or method refers to a single callable
object and piece of code. if you care about the type of the argument,
you must say so explicitly:

class A:
def dothing(self, obj):
if isinstance(obj, str):
self.dostringthing(obj)
elif isinstance(obj, (int,float)):
self.donumberthing(obj)
else:
self.dogenericthing(obj)

# ...

while python doesn't have C++-style function overloading, its
alternative also doesn't have the limitations that come with it.
From: Stefan Behnel on
Karsten Wutzke, 15.07.2010 20:45:
> Well, I'm most experienced in OO, so writing OO in Python seems like
> the way to start with Python. The visitor pattern uses single-
> dispatch, that is, it determines which method to call be the type of
> object passed in.

Well, then do that. Put the types into a dict and map them to the functions
to call, then call the function through the dict. That's a pretty common
way to do dispatching.


> Note, that I have an hierarchical object structure which I want to
> iterate over, so using OO looked natural to me. If there's a better
> approach, I'm all ears.

You speak in riddles, but my guess is that your problem is that you don't
want to dispatch mechanism to match only exact types but also subtypes. No
problem, just build your dict incrementally and add new types as they come
in. See this file for an example:

http://hg.cython.org/cython-devel/file/tip/Cython/Compiler/Visitor.py

Stefan

From: Stefan Behnel on
Karsten Wutzke, 15.07.2010 21:00:
>> Yes, typo, I meant strictly.
>
> Damn, I mean strongly. At least not for identifying which methods to
> call depending on the type/s.

I think you meant "statically typed".

http://c2.com/cgi-bin/wiki?StronglyTyped
http://www.c2.com/cgi/wiki?StaticTyping

Stefan

From: MRAB on
Stefan Behnel wrote:
> Karsten Wutzke, 15.07.2010 20:45:
>> Well, I'm most experienced in OO, so writing OO in Python seems like
>> the way to start with Python. The visitor pattern uses single-
>> dispatch, that is, it determines which method to call be the type of
>> object passed in.
>
> Well, then do that. Put the types into a dict and map them to the
> functions to call, then call the function through the dict. That's a
> pretty common way to do dispatching.
>
>
>> Note, that I have an hierarchical object structure which I want to
>> iterate over, so using OO looked natural to me. If there's a better
>> approach, I'm all ears.
>
> You speak in riddles, but my guess is that your problem is that you
> don't want to dispatch mechanism to match only exact types but also
> subtypes. No problem, just build your dict incrementally and add new
> types as they come in. See this file for an example:
>
> http://hg.cython.org/cython-devel/file/tip/Cython/Compiler/Visitor.py
>
Another variation: the dispatch table starts with entries for certain
types then it adds subtypes on demand:

def visit(self, obj):
try:
handler = self.dispatch_table[type(obj)]
except KeyError:
for disp_type, disp_func in self.dispatch_table.items():
if isinstance(obj, disp_type):
self.dispatch_table[type(obj)] = disp_func
handler = disp_func
else:
raise RuntimeError("Visitor does not accept object: %s"
% obj)
return handler(obj)
From: Matt McCredie on
Karsten Wutzke <kwutzke <at> web.de> writes:

> So, what is the de facto method in Python to handle source code generation?


Take a look at the NodeVisitor class in the ast module in python 2.6+.
The visitor pattern is implemented in the python standard library.

Matt