473,746 Members | 2,731 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

dynamic type changing

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. It seems that the next
call correctly uses the write() method of TemporaryFile (since we don't
see "changing type" in the output). However, type(tmp) still equals
TempFile. Not only that, tmp can still access the method dummy() that
exists only in TempFile.

#!/usr/bin/env python
from StringIO import StringIO
import tempfile

class TempFile(String IO, object):
"""A temporary file implementation that uses memory unless
either capacity is breached or fileno is requested, at which
point a real temporary file will be created and the relevant
details returned
"""
def __init__(self, buffer, capacity):
"""Creates a TempFile object containing the specified buffer.
If capacity is specified, we use a real temporary file once the

file gets larger than that size. Otherwise, the data is stored

in memory.
"""
self.capacity = capacity
if len(buffer) > capacity:
self = tempfile.Tempor aryFile()
self.write(buff er)
else:
super(TempFile, self).__init__( buffer)

def dummy(self):
pass

def write(self, str):
self.seek(0, 2) # find end of file
if((self.tell() + len(str)) >= self.capacity):
print "changing type"
flo = tempfile.Tempor aryFile()
flo.write(self. getvalue())
self = flo
print type(self)
else:
super(TempFile, self).write(str )
print "testing tempfile:"
tmp = TempFile("", 100)
ten_chars = "1234567890 "
tmp.write(ten_c hars * 5)
tmp.dummy()
print "tmp < 100: " + str(type(tmp))
tmp.write(ten_c hars * 5)
tmp.dummy()
print "tmp == 100: " + str(type(tmp))
tmp.write("the last straw")
tmp.dummy()
print "tmp > 100: " + str(type(tmp))

May 27 '06 #1
4 1838
an************* *@yahoo.co.uk 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 ?-)
It seems that the next
call correctly uses the write() method of TemporaryFile (since we don't
see "changing type" in the output). However, type(tmp) still equals
TempFile. Not only that, tmp can still access the method dummy() that
exists only in TempFile.

#!/usr/bin/env python
from StringIO import StringIO
import tempfile

class TempFile(String IO, object):
"""A temporary file implementation that uses memory unless
either capacity is breached or fileno is requested, at which
point a real temporary file will be created and the relevant
details returned
"""
def __init__(self, buffer, capacity):
"""Creates a TempFile object containing the specified buffer.
If capacity is specified, we use a real temporary file once the

file gets larger than that size. Otherwise, the data is stored

in memory.
"""
self.capacity = capacity
if len(buffer) > capacity:
self = tempfile.Tempor aryFile()
assigning to 'self' in a method doesn't impact the object itself - it
only rebinds the *local* name 'self' for the rest of the block.

If you want to change the class of an object, you must assign to
self.__class__ - but, while perfectly legal (and in fact the simplest
possible implementation of the state pattern in Python), it may be
somewhat risky.

(snip) def write(self, str):
self.seek(0, 2) # find end of file
if((self.tell() + len(str)) >= self.capacity):
print "changing type"
flo = tempfile.Tempor aryFile()
flo.write(self. getvalue())
self = flo
print type(self)


Same comment here.

(snip)

Now for a practical solution : what you want is the strategy pattern.
from StringIO import StringIO
from tempfile import TemporaryFile
import sys

class TempFile(object ):
"""A temporary file implementation that uses memory unless
either capacity is breached or fileno is requested, at which
point a real temporary file will be created and the relevant
details returned
"""

_strategies = (StringIO, TemporaryFile)

def __init__(self, buffer, capacity):
"""Creates a TempFile object containing the specified buffer.

If capacity is specified, we use a real temporary file once the
file gets larger than that size. Otherwise, the data is stored
in memory.
"""
self.capacity = capacity
self._delegate = self._strategie s[len(buffer) > self.capacity]()
self.write(buff er)

def write(self, value):
print >> sys.stderr, \
"about to write %d more characters" % len(value)
if isinstance(self ._delegate, self._strategie s[0]):
len_value = len(value)
if len_value >= self.capacity:
needs_new_strat egy = True
else:
self.seek(0, 2) # find end of file
needs_new_strat egy = \
self.tell() + len_value >= self.capacity

if needs_new_strat egy:
print >> sys.stderr, "changing strategy"
new_delegate = self._strategie s[1]()
new_delegate.wr ite(self.getval ue())
self._delegate = new_delegate

self._delegate. write(value)
def __getattr__(sel f, name):
# Takes care of automatic delegation,
# customize this according to your needs.
# Hint : this will only be called if normal lookup
# failed, so to control access to any _delegate's method,
# just implement a method with same name
try:
return getattr(self._d elegate, name)
except AttributeError:
# hide the delegation
e = "object '%s' has no attribute '%s'" \
% (self.__class__ .__name__, name)
raise AttributeError( e)
if __name__ == "__main__":
print "testing tempfile:"
tmp = TempFile("", 100)
ten_chars = "1234567890 "
tmp.write(ten_c hars * 5)
print "tmp < 100: ", tmp._delegate._ _class__.__name __
tmp.write(ten_c hars * 5)
print "tmp == 100: " , tmp._delegate._ _class__.__name __
tmp.write("the last straw")
print "tmp > 100: " , tmp._delegate._ _class__.__name __
May 27 '06 #2
>> 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 were the same thing so
that if you changed the class of self, the class of instance would also
change.

Thanks very much for your example. It has solved my problem and helped
me understand a new pattern at the same time.

May 28 '06 #3
On 28 May 2006 01:07:16 -0700, an************* *@yahoo.co.uk wrote:
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 were the same thing so
that if you changed the class of self, the class of instance would also
change.

Thanks very much for your example. It has solved my problem and helped
me understand a new pattern at the same time.


Bruno says you _can_ assign to __class__ but calls that "risky".
If you ever do feel the urge to assign a new value to some
object's __class__ it might be a good idea to first make certain
you can predict the behavior of the following:

class A:
msg = 'A'
def hmm(self):
print self.msg

class B:
msg = 'B'
def hmm(self):
print self.msg

x = A()
x.hmm()
x.__class__ = B
x.hmm()

class C:
def __init__(self):
self.msg = 'C'
def hmm(self):
print self.msg

class D:
def __init__(self):
self.msg = 'D'
def hmm(self):
print self.msg

x = C()
x.hmm()
x.__class__ = D
x.hmm()

*************** *********

David C. Ullrich
May 28 '06 #4
an************* *@yahoo.co.uk 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>votr e 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>
May 28 '06 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
1952
by: pizzy | last post by:
PROBLEM: I CAN'T GET THE LAST RESUTS TO WORK CORRECTLY. I WOULD PROVIDE THE CODE (AND WILL IF REQUESTED). BUT IN MY OWN WORDS I AM TRYING TO HAVE THE FIRST FORM DYNAMICALLY CREATE INPUT BOXES BASED ON THE NUMBER ENTERED. THEN ON THE SECOND FORM (WHICH IS CREATED BY THE FIRST FORM CALLING A FUNCTION) I WANT THE USER TO BE ABLE TO CLICK ON ONE OF THE CHECKBOXES AND SEE MORE INPUT BOXES APPEAR. HAS ANYONE DONE SOMETHING LIKE THIS? IF SO,...
5
6190
by: Todd Huish | last post by:
I have noticed something disturbing when retrieving datasets over a relatively slow line (multiple T1). I am looking at about 25 seconds to retrieve 500 rows via a php-odbc link. This same select from the cli is for all intents practicaly instantaneous. After much research I discovered that PHP by default uses a dynamic cursor type which can be quite a bit slower than a forward only cursor. BTW I have been searching forward only/read...
3
1312
by: Stephen Gennard | last post by:
Hello, I having a problem dynamically invoking a static method that takes a reference to a SByte*. If I do it directly it works just fine. Anyone any ideas why? I have include a example below... --
60
10180
by: Peter Olcott | last post by:
I need to know how to get the solution mentioned below to work. The solution is from gbayles Jan 29 2001, 12:50 pm, link is provided below: > http://groups.google.com/group/comp.lang.c++/msg/db577c43260a5310?hl > >Another way is to create a one dimensional array and handle the >indexing yourself (index = row * row_size + col). This is readily >implemented in template classes that can create dynamically allocated >multi-dimensional...
3
13748
by: NateDawg | last post by:
I'm reposting this. I'm kinda in a bind untill i get this figured out, so if anyone has some input it would sure help me out. Ok, I’ve noticed a few gridview problems floating around the forum. Everyone wants to do a java confirmation box when a user clicks the delete button. Fair enough, basic user design rules state that you should always confirm a delete action. There is also a consensus that the best way to do this is a template...
4
4214
by: coconet | last post by:
Server is Win2K3/IIS6. I have an ASPX page with this in the <headtag: <link rel="stylesheet" type="text/css" href="<% Response.Write( "http://" + Request.ServerVariables.ToString() + this.ResolveUrl("~") + "styles/styledefault.aspx"); %>" />
1
4659
by: MaryamSh | last post by:
Hi, I am creating a Dynamic Search in my application. I create a user control and in Page_load event I create a dynamic dropdownlist and 2 dynamic button (Add,Remove) By pressing Add button ,another row will be created with the same control (I mean another dropdown and 2 button) and so on. and by pressing Remove button the selecetd row will be removed. I used viewstate to keep my value for postback, I want by changing selectedvalue of...
0
3500
by: MaryamSh | last post by:
Create Dynamic Dropdownlist Controls and related event -------------------------------------------------------------------------------- Hi, I am creating a Dynamic Search in my application. I create a user control and in Page_load event I create a dynamic dropdownlist and 2 dynamic button (Add,Remove) By pressing Add button ,another row will be created with the same control (I mean another dropdown and 2 button) and so on. and by...
2
4462
Frinavale
by: Frinavale | last post by:
I've created a ASP.NET control that displays a "book" of schedules. It dynamically displays scheduling times and allows the user to page through the schedules. It also lets the user edit the schedule times if the user has permissions to edit schedules. When the user is not editing, or the user is not allowed to edit, the buttons that let the user edit are not displayed. If the user is allowed to edit schedules but they are not editing a link...
0
8974
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9350
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9285
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9218
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8229
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6772
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6060
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4586
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
3
2199
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.