Hmmm, I look at it the other way around: "Because Python is dynamically typed, all it cares about is interface". Any function will work with any object that supports the proper interface.
Also, as people have commented earlier, you should distinguish correctly between weak vs strong typing and static vs dynamic typing. Pure object oriented languages (where everything is an object, like Smalltalk) are usually strongly and dynamically typed. They are strongly typed because all objects are instances of a class (which is more or less equivalent to type) and there is no (simple) way to change an object's class. They are dynamically typed because any variable can hold any type of object. Languages that require you to specify all kinds of type information (statically typed) but let you overide it at will using casts (weakly typed), like C++, are very different. Python is at the dynamic end of the static/dynamic spectrum, and in the middle of the weak/strong spectrum.
The statement "In Python, the only reason you inherit is to inherit an implementation – to re-use the code in the base class." is accurate but misleading. You may not actually be inheriting the methods "def"ed, but rather the instance variables created (via code) in the constructor:
class aclass1:
def __init__(self):
self.var1=0
self.var2=0
self.var3=0
class aclass2 (aclass1): # inherits the instance variables only
Okay, it looks like multiple someones else have already jumped up and down on top of you for the 'weakly typed' misstatement. 8)
I cannot see how "Java's interface keyword would be wasted in Python." Guaranteeing a protocol (at compile time) is never a "waste", is it?
Don't get me wrong... I prefer python over java; I just think explicit interfaces are helpful. Sure: they're not necessary, but they aren't a waste.