Using python3.4. Here I want use singledispatch to dispatch different type in __mul__ method . The code like this :
class Vector(object):
    ## some code not paste  
    @functools.singledispatch
    def __mul__(self, other):
        raise NotImplementedError("can't mul these type")
    @__mul__.register(int)
    @__mul__.register(object)                # Becasue can't use Vector , I have to use object 
    def _(self, other):
        result = Vector(len(self))           # start with vector of zeros
        for j in range(len(self)):
            result[j] = self[j]*other
        return result
    @__mul__.register(Vector)                # how can I use the self't type
    @__mul__.register(object)                # 
    def _(self, other):
        pass # need impl 
As you can see the code , I want support Vector*Vertor , This has Name error
Traceback (most recent call last):
  File "p_algorithms\vector.py", line 6, in <module>
    class Vector(object):
  File "p_algorithms\vector.py", line 84, in Vector
    @__mul__.register(Vector)                   # how can I use the self't type
NameError: name 'Vector' is not defined
The question may be How can I use class name a Type in the class's method ? I know c++ have  font class statement . How python solve my problem ? And it is strange to see result = Vector(len(self)) where the Vector can be used in method body .
After have A look at http://lukasz.langa.pl/8/single-dispatch-generic-functions/ I can choose this way to implement :
import unittest
from functools import  singledispatch
class Vector(object):
    """Represent a vector in a multidimensional space."""
    def __init__(self, d):
        self._coords = [0 for i in range(0, d)]
        self.__init__mul__()
    def __init__mul__(self):
        __mul__registry = self.__mul__.registry
        self.__mul__ = singledispatch(__mul__registry[object])
        self.__mul__.register(int, self.mul_int)
        self.__mul__.register(Vector, self.mul_Vector)
    def __setitem__(self, key, value):
        self._coords[key] = value
    def __getitem__(self, item):
        return self._coords[item]
    def __len__(self):
        return len(self._coords)
    def __str__(self):
        return str(self._coords)
    @singledispatch
    def __mul__(self, other):
        print ("error type is ", type(other))
        print (type(other))
        raise NotImplementedError("can't mul these type")
    def mul_int(self,other):
         print ("other type is ", type(other))
         result = Vector(len(self))           # start with vector of zeros
         for j in range(len(self)):
             result[j] = self[j]*other
         return result
    def mul_Vector(self, other):
        print ("other type is ", type(other))
        #result = Vector(len(self))           # start with vector of zeros
        sum = 0
        for i in range(0,len(self)):
            sum += self._coords[i] * other._coords[i]
        return sum
class TestCase(unittest.TestCase):
    def test_singledispatch(self):
        # the following demonstrates usage of a few methods
        v = Vector(5)              # construct five-dimensional <0, 0, 0, 0, 0>
        for i in range(1,6):
            v[i-1] = i
        print(v.__mul__(3))
        print(v.__mul__(v))
        print(v*3)
if __name__ == "__main__":
    unittest.main()
The answer is strange :
other type is <class 'int'> [3, 6, 9, 12, 15] other type is <class '__main__.Vector'> 55 error type is <class 'int'> Traceback (most recent call last): File "p_algorithms\vector.py", line 164, in <module> print(v*3) File "C:\Python34\lib\functools.py", line 710, in wrapper return dispatch(args[0].__class__)(*args, **kw) File "p_algorithms\vector.py", line 111, in __mul__ raise NotImplementedError("can't mul these type")
v.__mul__(3)  can work but v*3 can't work. This is strange From my option v*3 is just the same as v.__mul__(3) .
Update after @Martijn Pieters's comment, I still want implement v*3 in class. So I try this
import unittest
from functools import  singledispatch
class Vector(object):
    @staticmethod
    def static_mul_int(self,other):
         print ("other type is ", type(other))
         result = Vector(len(self))           # start with vector of zeros
         for j in range(len(self)):
             result[j] = self[j]*other
         return result
    @singledispatch
    @staticmethod
    def __static_mul__(cls, other):
        print ("error type is ", type(other))
        print (type(other))
        raise NotImplementedError("can't mul these type")
    __mul__registry2 = __static_mul__.registry
    __mul__ = singledispatch(__mul__registry2[object])
    __mul__.register(int, static_mul_int)
    def __init__(self, d):
        self._coords = [0 for i in range(0, d)]
        self.__init__mul__()
    def __init__mul__(self):
        __mul__registry = self.__mul__.registry
        print ("__mul__registry",__mul__registry,__mul__registry[object])
        self.__mul__ = singledispatch(__mul__registry[object])
        self.__mul__.register(int, self.mul_int)
        print ("at last __mul__registry",self.__mul__.registry)
    # @singledispatch
    # def __mul__(self, other):
    #     print ("error type is ", type(other))
    #     print (type(other))
    #     raise NotImplementedError("can't mul these type")
    def mul_int(self,other):
         print ("other type is ", type(other))
         result = Vector(len(self))           # start with vector of zeros
         for j in range(len(self)):
             result[j] = self[j]*other
         return result
    def __setitem__(self, key, value):
        self._coords[key] = value
    def __getitem__(self, item):
        return self._coords[item]
    def __len__(self):
        return len(self._coords)
    def __str__(self):
        return str(self._coords)
class TestCase(unittest.TestCase):
    def test_singledispatch(self):
        # the following demonstrates usage of a few methods
        v = Vector(5)              # construct five-dimensional <0, 0, 0, 0, 0>
        for i in range(1,6):
            v[i-1] = i
        print(v.__mul__(3))
        print("type(v).__mul__'s registry:",type(v).__mul__.registry)
        type(v).__mul__(v, 3)
        print(v*3)
if __name__ == "__main__":
    unittest.main() 
This time .  v.__mul__(3) have error :
Traceback (most recent call last): File "test.py", line 73, in test_singledispatch type(v).__mul__(v, 3) File "/usr/lib/python3.4/functools.py", line 708, in wrapper return dispatch(args[0].__class__)(*args, **kw) TypeError: 'staticmethod' object is not callable
For me static method should act like the instance method.
 
     
    