#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    78
    Rep Power
    2

    My python understanding just had a minor setback...


    I've found an example of overloading on the net.
    and I really can't understand why and how this works... :S
    could someone please just give me a simple explaination?(without too many fancy words please)
    Code:
    class Test:
        def __init__(self, Number):
    	self.Number = Number
        def __add__(self, i):
    	return 1
    a = Test(1)
    
    print a+a
    doesnt my class and my object have scopes for themselves? why should they ruin my global scope? (or am I not using the global scope for +, even though I am in the "base" of the program.)
  2. #2
  3. Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Feb 2005
    Posts
    610
    Rep Power
    65
    When you apply + to an instance of your class then your class method __add__ takes over and returns 1

    print a + a shows a 1
    print a + 123 would still show a 1
    Real Programmers always confuse Christmas and Halloween because Oct31 == Dec25
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    78
    Rep Power
    2
    This must be some special rule for python then?
    I always thought of + as a .. function kinda, only accepting arguments in an uncommon manner..

    is there any special functions for - * /
    and == != < >
    and "or" "and"

    as well?
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    78
    Rep Power
    2
    hm, a+123 returns 1,
    but a+123+1 returns 2.

    so the first + uses the object method and inserts 123 as a variable. but the second + takes whatever that variable returns and just adds 1 to it.
  8. #5
  9. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,841
    Rep Power
    480
    Numbers are python objects.
    Code:
    >>> 1   .   __add__
    <method-wrapper '__add__' of int object at 0x17717c8>
    >>>
    and 1+1 uses the __add__ method for integers.

    Your version of __add__ returns an integer. Processing a+8+3 from left to right
    (a+8) gives integer 1
    1+3 gives 4.

    You could
    Code:
    class Test:
        def __init__(self, Number):
    	self.Number = Number
        def __add__(self, i):
    	return Test(1)  # return a Test object
    To get a list of all the special methods you'd have to consult the documentation. There a are a great many. This code will show methods for integers:

    import pprint; pprint.pprint(dir(0))
    Last edited by b49P23TIvg; February 15th, 2013 at 11:12 AM.
    [code]Code tags[/code] are essential for python code and Makefiles!
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Feb 2004
    Location
    San Francisco Bay
    Posts
    1,939
    Rep Power
    1313
    Originally Posted by leonnaley2
    This must be some special rule for python then?
    I always thought of + as a .. function kinda, only accepting arguments in an uncommon manner..

    is there any special functions for - * /
    and == != < >
    and "or" "and"

    as well?
    In Python, x + y is more or less equivalent to
    Code:
    x.__add__(y) if hasattr(x, "__add__") else y.__radd__(x)
    (Not quite: y.__radd__(x) is only used if x and y are of different types.)

    See also:
    http://docs.python.org/2/reference/d...-customization
    http://docs.python.org/2/reference/d...-numeric-types
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    78
    Rep Power
    2
    Thanks alot, I just had abit of an epihany regarding how this works don't think I'll get to use it for some time though, but also good to know how this stuff works
  14. #8
  15. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,841
    Rep Power
    480
    I fixed the code tag in my post.

    Suppose you had a class of for dimensional objects.

    You want to add two length units. There you'd define an __add__ method and the return value wouldn't be a number, you'd return a new instance of that class. Shown in repaired previous post. Let's examine strings before my example becomes too complicated. Both __mul__ and __rmul__ must be defined for str type, but str should not support division (or subtraction).
    Code:
    >>> 'xxxxxxxx' == 8*'x' == 'x'*8
    True
    >>> hasattr(str,'__rmul__')
    True
    >>> hasattr(str,'__sub__')
    False
    >>> 'abc' - 'a'
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unsupported operand type(s) for -: 'str' and 'str'
    [code]Code tags[/code] are essential for python code and Makefiles!
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    78
    Rep Power
    2
    yea, so I could do this:

    Code:
    #!/usr/bin/python
    
    class SuperString():
        def __init__(self, String):
    	self.String = String
        def __sub__(self, OtherString):
    	return self.String.replace(OtherString, "")
    
    
    sMyString = SuperString("Test")
    
    print(sMyString-"e")
    and get "Tst" as the output
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2007
    Location
    Joensuu, Finland
    Posts
    431
    Rep Power
    67
    Originally Posted by leonnaley2
    yea, so I could do this:

    Code:
    #!/usr/bin/python
    
    class SuperString():
        def __init__(self, String):
    	self.String = String
        def __sub__(self, OtherString):
    	return self.String.replace(OtherString, "")
    
    
    sMyString = SuperString("Test")
    
    print(sMyString-"e")
    Even nicer, you could subclass str:

    Code:
    >>> class SuperString(str):
    	def __init__(self, string):
    		str.__init__(self, string)
    	def __sub__(self, other_string):
    		return SuperString(self.replace(other_string, ''))
    
    	
    >>> s = SuperString('Test')
    >>> s - 'e'
    'Tst'
    >>> type(s - 'e')
    <class '__main__.SuperString'>
    My armada: openSUSE 13.1 (home desktop, home laptop), Crunchbang Linux 11 (mini laptop, work laptop), Android 4.2.1 (tablet)
  20. #11
  21. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    78
    Rep Power
    2
    Oh ye, nice this makes everything else work aswell, ofc how silly of me

IMN logo majestic logo threadwatch logo seochat tools logo