tags:

views:

35

answers:

2

what's the way to do in python the following in C++?

B* b = new D();
b->virtual_fn();

Which would call virtual_fn in D. Are there a form of references to do this?

+2  A: 

Effectively, all instance methods in Python are virtual and types are inferred. For example, this works:

class Vehicle:
  def __init__(self, lp):
    self.license_plate = lp
  def alert(self):
    raise NotImplementedError("Must implement this!")

class Boat(Vehicle):
  def alert(self):
    print "honk, honk!"

class Car(Vehicle):
  def alert(self):
    print "meep meep!"

class FireEngine(Vehicle):
  def alert(self):
    print "woo woo!"

vehicles = [Boat('!'), Car('ADJ-4891'), FireEngine('FRM-1498')]

for v in vehicles:
    print v.license_plate + ': ' + v.alert()

# prints:
# !: honk, honk!
# ADJ-4891: meep meep!
# FRM-1498: woo woo!
John Feminella
Good answer! Thanks for the list example. I can't check your answer too but I voted it up.
piotr
+2  A: 

In Python, values have types not variables. The latter are simply useful names for the values that they are currently bound to. Since variables do not have types, if you create a D object and bind a variable to it, then you get the methods explicitly defined by the D class and any in the B class that have not been replaced. Effectively, everything is virtual.

Now if you want to call a method in B that has been replaced in D, you have to call the method and pass self explicitly. Here's an example with id() doctored to protect the innocent.

>>> class B(object):
...     def virtual_fn(self):
...         print 'in B.virtual_fn() for', id(self)
...     def other_virtual_fn(self):
...         print 'in B.other_virtual_fn() for', id(self)
...     def call_virtual(self):
...         print 'in B.call_virtual() for', id(self)
... 
>>> class D(B):
...     def virtual_fn(self):
...         print 'in D.virtual_fn() for', id(self)
... 
>>> b_obj = B()
>>> d_obj = D()
>>> id(b_obj)
1
>>> id(d_obj)
2
>>>
>>> b_obj.virtual_fn()
in B.virtual_fn() for 1
>>> d_obj.virtual_fn()
in D.virtual_fn() for 2
>>> d_obj.other_virtual_fn()
in B.other_virtual_fn() for 2
>>>
>>> B.virtual_fn(d_obj)
in B.virtual_fn() for 2
>>>
>>> d_obj.call_virtual()
in B.call_virtual() for 2
in D.virtual_fn() for 2
>>>

Remember that d_obj.virtual_fn() is essentially syntactical sugar for D.virtual_fn(d_obj). So if you want to explicitly call a hidden method of a base class, you do so without the sugar - B.virtual_fn(d_obj). I would highly recommend reading the Method Resolution Order (mro) document from Python 2.3. It really explains how all of this works rather well.

Edit

After reading the question again, I added the call_virtual stuff since I'm pretty sure that this is what you are interested in.

D.Shawley