0

I need to extend the class Client from SUDS module... For example i have this simple code which works fine

client = Client(wsdl, username = USERNAME, password = PASSWORD, headers = {'Content-Type': 'application/soap+xml'}, plugins = [VapixHelper()])

rules = client.service.GetActionRules()

And so i need to add some extra methods for this class so i try to do it like this:

class Vapix(Client):
    def __init__(self, args):
        globals().update(vars(args))
        USERNAME, PASSWORD = user_data.split(':')
        super(Vapix, self).__init__(wsdl, username = USERNAME, password = PASSWORD, headers = {'Content-Type': 'application/soap+xml'}, plugins = [VapixHelper()])

    def setActionStatus(self, status):
        print super(Vapix, self).service.GetActionRules()

And i get this error instead of the result:

Traceback (most recent call last):
  File "vapix.py", line 42, in <module>
    client.setActionStatus(True)
  File "vapix.py", line 36, in setActionStatus
    print super(Vapix, self).service.GetActionRules()
AttributeError: 'super' object has no attribute 'service'
hjpotter92
  • 78,589
  • 36
  • 144
  • 183
Kin
  • 4,466
  • 13
  • 54
  • 106
  • 3
    Just use `self.service`. – BrenBarn Mar 28 '14 at 07:47
  • @BrenBarn nice one, thanks... May be you can provide some info where is the difference between `super(Vapix, self)` and `self` when need to call parent class ? – Kin Mar 28 '14 at 07:49
  • 1
    you may want to read http://stackoverflow.com/questions/576169/understanding-python-super-and-init-methods – icedtrees Mar 28 '14 at 07:51
  • 1
    You're not calling the parent class there, you're accessing an attribute of the *instance*. As loong as you properly call the superclass *methods* (like you're doing with `__init__`), the right attributes will just be there on the instance and you can use them as normal. – BrenBarn Mar 28 '14 at 07:51

1 Answers1

2

You are not overriding a service() method, so you don't need to use super() to find an original method; remove the super() call and access the attribute directly on self instead:

def setActionStatus(self, status):
    print self.service.GetActionRules()

super() is only needed if you need to search the base classes (in Method Resolution Order, MRO) for a method (or other descriptor object), often because the current class has redefined that name.

If you need to call a base class foo but the current class implements a foo method, then you cannot use self.foo() and you need to use super() instead. You had to use super() for __init__ for example; your derived class has its own __init__ method, so calling self.__init__() would recursively call that same method, but super(Vapix, self).__init__() works because super() looks at the MRO of self, finds Vapix in that ordering, then goes looking for the next class that has an __init__ method.

Here service is an instance attribute; it is defined directly on self and isn't even a method.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • yeah, already understood this... One move thing on your answer... What should i do if i wanted to override parent method? – Kin Mar 28 '14 at 07:54
  • 1
    @Kirix: *then* you name the method the same and use `super()` to invoke the parent method still. – Martijn Pieters Mar 28 '14 at 07:54