4

Code:

class C:
    def __init__(self, **kwargs):
        self.w = 'foo'
        self.z = kwargs['z']
        self.my_function(self.z)    
    def my_function(self, inp):
        inp += '!!!'

input_args = {}
input_args['z'] = 'bar'
c = C(**input_args)
print c.z

Expected Result

bar!!!

Actual Result

bar

How do you call a class' method in init?

Community
  • 1
  • 1
Noob Saibot
  • 4,573
  • 10
  • 36
  • 60

4 Answers4

5

Modify self.z, not inp:

def my_function(self, inp):
    self.z += '!!!'

Secondly strings are immutable in python, so modifying inp won't affect the original string object.

See what happens when self.z is mutable object:

class C:
    def __init__(self, ):
        self.z = []
        self.my_function(self.z)    
    def my_function(self, inp):
        inp += '!!!'
        print inp
        print self.z

C()        

output:

['!', '!', '!']
['!', '!', '!']
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
4

The problem is, you are not actually modifying the value of self.z

Try this instead

class C:
    def __init__(self, **kwargs):
        self.w = 'foo'
        self.z = kwargs['z']
        self.z = self.my_function(self.z)    

    def my_function(self, inp):
        inp += '!!!'
        return inp

input_args = {}
input_args['z'] = 'bar'
c = C(**input_args)
print c.z
karthikr
  • 97,368
  • 26
  • 197
  • 188
0

Your code does not contain any classmethods.

You are in fact calling the instance method which you are calling, it just doesn't do anything other than return None.

Also, if this is python 2.7, in general things will work better if you inherit from object (or some other class).

Marcin
  • 48,559
  • 18
  • 128
  • 201
-1

You are correctly calling the class method, however parameters are passed by value, not by reference. If you modify inp in the method my_function, it doesn't reflect on self.z.

Pit
  • 3,606
  • 1
  • 25
  • 34
  • 1
    Not downvoted. But in python parameters are passed by reference. The problem is that the reference is changed when do a `+=` to strings or numbers (but list won't). – neuront Jul 11 '13 at 16:45
  • @neuront Only mutable parameters are passed by reference, immutable are passed by value. [Blair Conrad](http://stackoverflow.com/users/1199/blair-conrad) has written a [extensive answer](http://stackoverflow.com/a/986145/758165) on this topic. But you are right in the regard that I should not have generalized. – Pit Jul 11 '13 at 16:49
  • No parameters at all are passed by reference. I downvoted this because there is no class method. – Marcin Jul 11 '13 at 16:52
  • 1
    @Pit The first line in the answer you link correctly states that parameters are passed by value. They are passed *only* by value. – Marcin Jul 11 '13 at 16:52
  • @Marcin I should have rephrased my comment. As Blair put it, the reference to a mutable object gets passed by value. So you are correct in that regard. However, I do think that `my_function` is a class method. Could you elaborate on that? – Pit Jul 11 '13 at 16:56
  • @Pit It's not a classmethod. What makes you think that? Go read about what a classmethod is. – Marcin Jul 11 '13 at 16:57
  • @Mercin Oh, I'm sorry. I mixed up the definition of a classmethod and a module-function. – Pit Jul 11 '13 at 17:04
  • 1
    @Pit you're slightly incorrect. In both cases, (the references to) the objects are passed by value; the difference is handled by the way Python implements operators as method calls. When an object has an `__iadd__` attribute (like `list`), `a += b` will be translated to `a.__iadd__(b)`, but when that operation is performed on objects without `__iadd__`, the translation defaults to `a = a.__add__(b)`. – JAB Jul 11 '13 at 17:10