Identifying a class type - bad practice?

J

James Harris

I am writing some code to form a tree of nodes of different types. The
idea is to define one class per node type such as

class node_type_1(node):
<specific properties by name including other node types>
class node_type_2(node):
<specific properties by name including other node types>
etc

(Class "node" would hold any common properties).

When walking the tree I need to know what type of node I'm dealing
with so polymorphism isn't generally useful. The action to be taken
depends on the node type. Two options appear to be useful: __class__
and isinstance. I know the latter will match the instance against any
superclass and the former will match one class only.

My question is: is this the Pythonic way to deal with such a tree? Is
there a better way? In C I would use structs where one field was a tag
indicating the kind of struct.

James
 
E

Ethan Furman

James said:
I am writing some code to form a tree of nodes of different types. The
idea is to define one class per node type such as

class node_type_1(node):
<specific properties by name including other node types>
class node_type_2(node):
<specific properties by name including other node types>
etc

(Class "node" would hold any common properties).

When walking the tree I need to know what type of node I'm dealing
with so polymorphism isn't generally useful. The action to be taken
depends on the node type. Two options appear to be useful: __class__
and isinstance. I know the latter will match the instance against any
superclass and the former will match one class only.

My question is: is this the Pythonic way to deal with such a tree? Is
there a better way? In C I would use structs where one field was a tag
indicating the kind of struct.

James

I would recommend going with isinstance. An instance of node_type_2
will not be an instance node_type_1, so no worries there, and it leaves
open the option of subclassing further if you need to later on.

~Ethan~
 
A

André

I am writing some code to form a tree of nodes of different types. The
idea is to define one class per node type such as

class node_type_1(node):
  <specific properties by name including other node types>
class node_type_2(node):
  <specific properties by name including other node types>
etc

(Class "node" would hold any common properties).

When walking the tree I need to know what type of node I'm dealing
with so polymorphism isn't generally useful. The action to be taken
depends on the node type. Two options appear to be useful: __class__
and isinstance. I know the latter will match the instance against any
superclass and the former will match one class only.

My question is: is this the Pythonic way to deal with such a tree? Is
there a better way? In C I would use structs where one field was a tag
indicating the kind of struct.

James

I would probably go with hasattr(instance, 'what_I_want')

André
 
C

Chris Rebert

I am writing some code to form a tree of nodes of different types. The
idea is to define one class per node type such as

class node_type_1(node):
 <specific properties by name including other node types>
class node_type_2(node):
 <specific properties by name including other node types>
etc

(Class "node" would hold any common properties).

When walking the tree I need to know what type of node I'm dealing
with so polymorphism isn't generally useful. The action to be taken
depends on the node type.

I'm sure it relates to the exact type of tree you're walking and the
calculation you're doing on it, but what is the reason why your code,
which in the abstract sounds like it will vaguely resemble this:

def walk_tree(tree):
if isinstance(tree, node_type_1):
#code
walk_tree(subtree)
elif isinstance(tree, node_type_2):
#code
walk_tree(subtree)
#etc...

can't be written instead as:

class node_type_1:
def walk_tree(self):
#code
self.subtree.walk()

class node_type_2:
def walk_tree(self):
#code
self.subtree.walk()

#etc

?

Cheers,
Chris
 
J

James Harris

I'm sure it relates to the exact type of tree you're walking and the
calculation you're doing on it, but what is the reason why your code,
which in the abstract sounds like it will vaguely resemble this:

def walk_tree(tree):
    if isinstance(tree, node_type_1):
        #code
        walk_tree(subtree)
    elif isinstance(tree, node_type_2):
        #code
        walk_tree(subtree)
    #etc...

can't be written instead as:

class node_type_1:
    def walk_tree(self):
        #code
        self.subtree.walk()

class node_type_2:
    def walk_tree(self):
        #code
        self.subtree.walk()

#etc

Interesting idea. This may be a better and a more OO solution than
what I had in mind. I'm not sure if I can use this but I'll see how it
fits in as the work progresses.

The tree is for a compiler. Initially the tree is for parsing of
source code. Then it will need to be processed and changed as further
compiler phases are written. I don't know yet whether it will be
easier to modify the tree or to create a new one for each phase.

So I guess whether I use the idea depends on the commonality of
operations.

James
 
B

Bruno Desthuilliers

James Harris a écrit :
Interesting idea.

Basic OO stuff, really. I'd say it's even the whole point of OO.

(snip)
The tree is for a compiler. Initially the tree is for parsing of
source code. Then it will need to be processed and changed as further
compiler phases are written. I don't know yet whether it will be
easier to modify the tree or to create a new one for each phase.

So I guess whether I use the idea depends on the commonality of
operations.

You may want to have a look at the "composite" and "visitor" design
patterns. AST are canonical use case for these patterns.


HTH
 
G

greg

James said:
I don't know yet whether it will be
easier to modify the tree or to create a new one for each phase.

You can create a new tree using this style as
well. Just have each method create and return a
new node instead of modifying the existing one.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top