[Twisted-Python] Why classes in twisted.protocols.basic use "static member" to store states?
Hi, I'm a newbie. After went through the source code in twisted.protocols.basic, I found it's really strange that all classes in twisted.protocols.basic use "static member" to store states. Take class StatefulStringProtocol as the example. Some Factory will creates a group of StatefulStringProtocol instances which share the static member "state". But why all instances MUST have the same state? In my opinion, instance A may be in the "handshaking" state, while instance B may be in the "data sending" state. The static member can not represent this case. Therefore, I think protocols should use "member variable" rather that "static member": class StatefulStringProtocol: def __init__(self): self.state = 'init' ... Could you plz give me some clue? I am a little confused. Most possibly, I misunderstanding the design about protocols-factory. Thank you. ShenLei
Quoting ?? <littlesweetmelon@gmail.com>:
Hi, I'm a newbie. After went through the source code in twisted.protocols.basic, I found it's really strange that all classes in twisted.protocols.basic use "static member" to store states. Take class StatefulStringProtocol as the example. Some Factory will creates a group of StatefulStringProtocol instances which share the static member "state". But why all instances MUST have the same state? In my opinion, instance A may be in the "handshaking" state, while instance B may be in the "data sending" state. The static member can not represent this case. Therefore, I think protocols should use "member variable" rather that "static member":
class StatefulStringProtocol: def __init__(self): self.state = 'init' ...
Could you plz give me some clue? I am a little confused. Most possibly, I misunderstanding the design about protocols-factory.
In fact, you're misunderstanding Python :). The fact that the variable is defined as class member doesn't make shared between instances. You can see some explanation here: http://diveintopython.org/object_oriented_framework/class_attributes.html. -- Thomas
No, I don't think so. ^_^ You can see it from the last lines in you recommend document:
d.count 2 c.count 2
Instance c & d indeed share the class attribute "count". You can try it more explicitly:
class A: ... i = 0 ... p = A() q = A() A.i = 2 p.i 2 q.i 2 Again, instance p & q share the class attribute "i".
-- ShenLei
甜瓜 wrote:
No, I don't think so. ^_^ You can see it from the last lines in you recommend document:
No you can't, because you've misunderstood.
d.count 2 c.count 2
Instance c & d indeed share the class attribute "count". You can try it more explicitly:
class A: ... i = 0 ... p = A() q = A() A.i = 2 p.i 2 q.i 2 Again, instance p & q share the class attribute "i".
They share it UNTIL IT IS MODIFIED. So, to continue the above example, the relevant bit would be:
p.i=3 p.i 3 q.i 2
Effectively, classes in python serve as templates to create instances. If you create two instances of a class and modify the class, then both are modified - however, if you then modify an instance, the class and other instances are not, and those modifications override any conflicting ones on the class. Continuing the above example:
p.__dict__ {'i': 3} q.__dict__ {}
So, because we've modified "p", the attribute is set in the instance dict. q remains unmodified, and the getattr call will continue through to the class. Doing this: class AProtocol: INITIALSTATE = 'foo' ..is just a quick way to get INITIALSTATE set on every instance. The ONLY circumstance you need worry about these variables being shared is if you use a mutable variable and mutate it in place. For example:
class BProtocol: ... SOMEDATA = {} ... p = BProtocol() q = BProtocol() p.SOMEDATA['a'] = 1 q.SOMEDATA {'a': 1}
If you don't want that to happen, don't do it. Twisted doesn't.
On 30 Mar 2007, at 19:23, 甜瓜 wrote:
Instance c & d indeed share the class attribute "count". You can try it more explicitly:
class A: ... i = 0 ... p = A() q = A() A.i = 2 p.i 2 q.i 2
Ah, but continuing:
p.i = 5 p.i 5 q.i 2
i is still not a class attribute in the same way it might be for Java or C++.
Oh, I see. Thank you very much.
* Tim Allen <screwtape@froup.com> [2007-03-30 20:04:18 +1000]:
Ah, but continuing:
p.i = 5 p.i 5 q.i 2
i is still not a class attribute in the same way it might be for Java or C++.
It would probably be more correct to say that "value types" and "assignment" work differently in Python compared with Java/C++. More specifically, in Java/C++, "value types" like int or Integer are mutable, and the "=" operator mutates them. In python, they are immutable, and the "=" operator never mutates objects, but instead inds a variable / attribute / etc. to a new object reference. -- mithrandi, i Ainil en-Balandor, a faer Ambar
participants (5)
-
Phil Mayers
-
Thomas Hervé
-
Tim Allen
-
Tristan Seligmann
-
甜瓜