[EMAIL PROTECTED] a écrit : >>>I'm working on a "TempFile" class that stores the data in memory until >>>it gets larger than a specified threshold (as per PEP 42). Whilst >>>trying to implement it, I've come across some strange behaviour. Can >>>anyone explain this? > > >>>The test case at the bottom starts a TempFile at size 50 and prints its >>>type. It then increases the size to the threshold at which point >>>"self" is changed to being a TemporaryFile. > >>Changed how ?-) > > Just by being assigned with a TemporaryFile object. > > I thought that if > you do > > instance = TempFile() > > that "instance" and "self" defined in the Class
They are not defined "in the class". > were the same thing so > that if you changed the class of self, > the class of instance would also > change. Yes, of course - but you didn't change the class of 'self' !-) Python's "variable" are really just names "bound to" (referring to) objects. Rebinding (ie: assignment) does not impact the object (well, not directly), it just associate the name to another object. This is totally different from changing the state of the object. There's nothing magical about the name 'self' - FWIW, you could replace it by any other valid python identifier. In Python, a method is just a plain function that takes the instance as the first argument. This function is wrapped into a method descriptor (google for python's descriptor protocol - it's the same thing that is used for properties) that takes care of feeding the function with the instance. FWIW, given: class Obj(object): def someMethod(self): pass obj = Obj() then obj.someMethod() is the same as Obj.someMethod(obj) or also: obj.someMethod.im_func(obj) So, inside someMethod's code, normal scoping rules apply. This means that 'self' is a *local* name, and rebinding it only affect the local scope. And it doesn't "change the type" of the object (previously) bound to 'self', it really re-bind 'self' to another object (IOW: makes 'self' a reference to another object). Just like it does in any other Python code. As I wrote, to dynamicall change the class of an object, you must rebind obj.__class__ to another class, ie: class Other(object): def __init__(self, name): self.name = name obj = Obj() print type(obj) obj.__class__ = Other print type(obj) Now a big warning : this is not garanteed to work seamlessly ! 'obj' will keep it's original instance attributes, and the instance attributes normally set up by the new class (here, 'Other') won't exist since the class initializer won't be called. So, while this may not be a problem if the original and new classes are designed to be used that way (which makes a very straightforward implementation of the state pattern), it's usually not a good idea to do such a thing. FWIW, it's usually simpler and safer - evn if a bit less elegant - to implement the state pattern just like I did in the example: by using composition/delegation. > Thanks very much for your example. <reverence>votre humble serviteur, Messire</reverence> > It has solved my problem and helped > me understand a new pattern at the same time. <ot> FWIW, there's no clear, well defined boudary between State and Strategy - the main difference depends mostly on the intention. Your use case could also be viewed as a State pattern, with 2 states : buffer < capacity, and buffer >= capacity. But the intention is not to know in which state is the object - on the contrary, you're trying to hide away the chosen implementation (StringIO or TemporayFile) - so it's really a Strategy IMHO. </ot> -- http://mail.python.org/mailman/listinfo/python-list