0

According to this answer Change attribute after each object calling, I thought that call method should do something to its instance everytime its called. I'm trying to use this in my code but I'm wrong somewhere.

class switcher():
    current_index = -1

    def __call__(self):
        self.current_index +=1

sw = switcher()
print sw.current_index
print sw.current_index

output: -1

output: -1

I think that it should return this:

output: 0

output: 1

because it increments the current_index value everytime the sw instance is called.

Obviously I'm wrong, could you tell me where is the problem please?

Community
  • 1
  • 1
Milano
  • 18,048
  • 37
  • 153
  • 353

3 Answers3

2

I have no idea what you really want to do but you need to actually call the instance which you are not doing:

sw = switcher() # creates instance, does not call __call__ in your class
sw() # call/increment calling the instance 
print(sw.current_index)
sw() # call/increment calling the instance 
print(sw.current_index)
0 # after first sw() call 
1  # after second sw() call 

The __call__ makes your instance callable, if you don't call the instance then it does nothing. Creating an instance has nothing to do with __call__

The property approach in the answer you linked to seems to be what you are trying to do.

Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
  • 1
    @MalikBrahimi, that has nothing to do with the problem, it is completely irrelevant to the issue – Padraic Cunningham Jun 26 '15 at 23:52
  • No I'm not using __call__ and __init__ interchangeably, I do know that init is called when and only when the instance is being created. I thought that __call__ is being called everytime I "use" the instance of the method. It means whenever I use (I thought call) attribute or a method. – Milano Jun 26 '15 at 23:54
  • 1
    @Milan, no call is used when you call the instance, it makes the object callable, it does not mean it gets called every time you use the instance to access the attribute. Using a property is about the only reasonable way to do what you want – Padraic Cunningham Jun 26 '15 at 23:56
  • @MalikBrahimi, there is nothing in the question to suggest the variable should not be shared – Padraic Cunningham Jun 26 '15 at 23:57
  • @PadraicCunningham Thanks for explaining it. Is there something I can use to change the attribute everytime I do anything with the instance like accessing the attribute or using a method? I know that I can use __@property but Is there a method like call and init which can do that? – Milano Jun 26 '15 at 23:58
  • @Milan, you could simply decrement in the methods but as far as decrementing when you access the attribute directly goes, there is no simple way I can think of doing it – Padraic Cunningham Jun 27 '15 at 00:03
  • @Milan, what is it that you are actually trying to do, is there a specific reason you want the behaviour? – Padraic Cunningham Jun 27 '15 at 00:12
  • @PadraicCunningham Let's clean up the comments. – Malik Brahimi Jun 27 '15 at 00:13
1

First: the current_index attribute belongs to the class, not to the object instance, as you require. You need to assign it within

__init__(self) 

Second: call the object instance, as described in the previous answer.

Pynchia
  • 10,996
  • 5
  • 34
  • 43
  • It's not a matter of convention. Class and instance attributes behave quite differently. He says he wants to operate on the instance – Pynchia Jun 26 '15 at 23:36
  • Although this is not the main problem I agree that the attribute should be an instance attribute. – Malik Brahimi Jun 26 '15 at 23:53
1

You do not understand the difference between the constructor and the caller methods of a class:

__init__ := 'instance is created when class is invoked, Switcher()'
__call__ := 'func is executed when instance is invoked, switcher()'
class Switcher():

    def __init__(self):
        self.current_index = -1

    def __call__(self):
        self.current_index += 1
switcher = Switcher() # instance created calling __init__ -> current_index = -1
switcher() # instance just been invoked, calling __call__ -> current_index = 0
Malik Brahimi
  • 16,341
  • 7
  • 39
  • 70