Override Methods
__float__, executed by float()
__hex__, executed by hex()
__int__, executed by int()
__long__, executed by long()
__oct__, executed by oct()
#!/usr/bin/python
 
class Integer(object):
 
    def __init__(self, value):
        self._value = value;
 
    @property
    def value(self):
        return self._value
 
    @value.setter
    def value(self, v):
        self._value = v;
 
    @value.deleter
    def value(self):
        del self._value
 
    def __str__(self):
        return "Value: %d" % self._value
 
    def __float__(self):
        return float(self._value)
 
def main():
    i1 = Integer(-10);
 
    print(float(i1)) # -10.0
 
if __name__ == '__main__':
    main()
		
__abs__, executed by abs()
__pow__, executed by pow()
__divmod__, executed by divmod()
#!/usr/bin/python
 
class Integer(object):
 
    def __init__(self, value):
        self._value = value;
 
    @property
    def value(self):
        return self._value
 
    @value.setter
    def value(self, v):
        self._value = v;
 
    @value.deleter
    def value(self):
        del self._value
 
    def __str__(self):
        return "Value: %d" % self._value
 
    def __abs__(self):
        return Integer(abs(self._value))
 
    def __pow__(self, p):
        return Integer(pow(self._value, p))
 
    def __divmod__(self, other):
        return (Integer(self._value/other._value), Integer(self._value%other._value))
 
def main():
    i1 = Integer(-10);
 
    print(abs(i1)) # 10, __abs__
    print(pow(i1, 2)) # 100, __pow__
 
    a, b = divmod(Integer(10), Integer(3)) # __divmod__
    print(a, b) # 3 1
 
if __name__ == '__main__':
    main()
		
__delattr__, execuate when an attribute is deleted, work with delattr function
__getattr__, execute when the accessed attribute does not exist, work with getattr function
__setattr__, execute when an attribute is assigned a value, work with setattr function
#!/usr/bin/python
 
class Vehicle(object):
 
    def __init__(self, brand, year):
        self._brand = brand
        self._year = year
 
    @property
    def brand(self):
        return self._brand
 
    @brand.setter
    def brand(self, b):
        self._brand = b;
 
    @brand.deleter
    def brand(self):
        del self._brand
 
    @property
    def year(self):
        return self._year
 
    @year.setter
    def year(self, y):
        self._year = y
 
    @year.deleter
    def year(self):
        del self._year
 
    def __getattr__(self, name):
        print("Call __getattr__ ... %s" % name)
        if name == '_brand':
            return 'Br'
        if name == '_year':
            return 0
 
    def __str__(self):
        return "Brand: %s, year: %d" % (self._brand, self._year)
 
def main():
    v = Vehicle("Buick", 1998)
    print(v)
 
    delattr(v, 'year')
    print(v) # call __getattr__
 
if __name__ == '__main__':
    main()
	
		
__contains__, execuate by in
#!/usr/bin/python
class MyRange:
    def __init__(self, start, stop, step):
        self.__sequence = range(start, stop, step);
 
    def __str__(self):
        s = '[';
        for i in self.__sequence:
            s = s + ' ' + str(i)
 
        return s + ' ]'
 
    def __contains__(self, value):
        return value in self.__sequence
 
def main():
    l = MyRange(0, 10, 1);
 
    print(1 in l) # True, __contains__
    print(10 in l) # False
 
if __name__ == '__main__':
    main();
		
__getattribute__, execuate no matter the attribute exists or not
#!/usr/bin/python
 
class Vehicle(object):
 
    def __init__(self, brand):
        self.__brand = brand
 
    def __str__(self):
        return "Brand: %s" % self.__brand
 
    def __getattribute__(self, name):
        return 'Hello World!'
 
def main():
    v = Vehicle("Buick")
 
    print(v._Vehicle__brand) # Hello World!, attribute exist
 
    print(v.year) # Hello World!, attribute does not exist
 
if __name__ == '__main__':
    main()
		
__len__, len()
__getitem__, []
__setitem__, []
__delitem__, []
  • provides subscript access
  • throw IndexError
  • class MyRange:
        def __init__(self, start, stop, step):
            self.__sequence = list(range(start, stop, step))
     
        def __str__(self):
            s = '[';
            for i in self.__sequence:
                s = s + ' ' + str(i)
     
            return s + ' ]'
     
        def __len__(self):
            return len(self.__sequence)
     
        def __getitem__(self, index):
            return self.__sequence[index]
     
        def __setitem__(self, index, value):
            self.__sequence[index] = value
     
        def __delitem__(self, index):
            del self.__sequence[index]
     
    def main():
        l = MyRange(0, 10, 1)
     
        print(l) # [0 1 2 3 4 5 6 7 8 9],  __str__
        print(len(l)) # 10,  __len__
        print(l[1]) # 1, __getitem__
        print(l[:3]) # [0, 1, 2], __getitem__
        l[1] = 100 # __setitem__
        print(l) # [0 100 2 3 4 5 6 7 8 9]
     
        del l[1]
        print(l) [0 2 3 4 5 6 7 8 9]
     
    if __name__ == '__main__':
        main();
    		
    __iter__, building an iterator, executed by iter()
    __next__, get next element in an iterator, executed by next()
  • support iterators
  • Define next function, iterable and iterator are same, it is consumed in a single iteration
  • #!/usr/bin/python
    class MyRange:
        def __init__(self, m = 0):
            self.max = m
            self.n = 0
    
        def __iter__(self):
            print('Call __iter__ ...')
            self.n = 0
            return self
    
        def __next__(self):
            print('Call __next__ ...')
            if self.n <= self.max:
                result = 2 ** self.n
                self.n += 1
                return result
            else:
                raise StopIteration('End of iteration ...')
     
    def main():
        l = iter(MyRange(4))
        while True:
            try:
                print(next(l))
            except StopIteration as err:
                print(err)
                break
    
    if __name__ == '__main__':
        main();
    		
    #!/usr/bin/python
    class RangeIterator:
        def __init__(self, start, stop, step):
            self.__sequence = list(range(start, stop, step))
            self.__nextIndex = 0;
     
        def __iter__(self):
            return self;
     
        def __next__(self):
            try:
                value = self.__sequence[self.__nextIndex];
            except IndexError:
                raise StopIteration
            else:
                self.__nextIndex += 1;
                return value;
    		
    #!/usr/bin/python
    from o import RangeIterator;
     
    l = RangeIterator(0, 10, 1); #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
     
    for e in l: #0 1 2 3 4 5 6 7 8 9
        print(e, end=' ')
    print()
     
    for e in l: #do not print anything
        print(e, end=' ')
     
    l2 = RangeIterator(0, 10, 1);
    i2 = iter(l2);
    while 1:
        try:
            value = next(i2)
        except StopIteration:
            break;
        else:
            print(value)
    		
    __call__, make object callable, callable(obj) returns True
    class Vehicle(object):
        """Document String: Define a Vehicle class"""
     
        def __init__(self, brand, year):
            print('Create a Vehicle ...')
            self._brand = brand;
            self._year = year;
     
        # make object callable
        # *args is used to allow passing variable arguments to the __call__() function
        # **kwargs is used to allow passing named arguments to the __call__() function
        def __call__(self, *args, **kwargs):
            print(args)
            print(kwargs)
     
    def main():
        v = Vehicle("Lincoln", 1998);
     
        v()
        v(10, 'Hello World', name = 'Lin') # [10, 'Hello World'] {'name': 'Lin'}
     
    if __name__ == "__main__":
    	main()
    		
    __hash__, can be checked by hash(), used by hashed collections including set, frozenset, and dict
    #!/usr/bin/python
     
    class Vehicle(object):
     
        def __init__(self, brand):
            self.__brand = brand
     
        def __str__(self):
            return "Brand: %s" % self.__brand
     
        def __hash__(self):
            return hash(self.__brand)
     
    def main():
        v = Vehicle("Buick")
        print(hash(v))
     
    if __name__ == '__main__':
        main()
    		
    __str__, executed by str()
  • define a class whose objects can be output with print function
  • #!/usr/bin/python
     
    class Vehicle(object):
     
        def __init__(self, brand):
            self.__brand = brand
     
        def __str__(self):
            return "Brand: %s" % self.__brand
     
    def main():
        v = Vehicle("Buick")
        print(v)
     
    if __name__ == '__main__':
        main()
    		
    __format__, executed by .format()
    #!/usr/bin/python
     
    class Vehicle(object):
     
        def __init__(self, brand):
            self.__brand = brand
     
        def __str__(self):
            return "Brand: %s" % self.__brand
     
        def __format__(self, formatstr):
            print(formatstr)
            return "Inside {1:{0}}".format(formatstr, self.__brand)
     
    def main():
        v = Vehicle("Buick")
     
        print('Vehicle |{:>20s}|'.format(v))
     
    if __name__ == '__main__':
        main()
    		
    Reference
  • Index – _
  • A Guide to Python's Magic Methods
  • Python How to Program, Chapter 8
  • Operator and Function Overloading