473,498 Members | 1,956 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

"Aliasing" an object's __str__ to a different method

I am attempting to write a class whose string representation changes
in response to external stimuli. While that effect is obviously
possible via other means, I attempted this method first and was
surprised when it didn't work, so I now want to know why :)

Given the following class definition:

class MyClass(object):

def Edit(self):
return "I, %s, am being edited" % (self)

def View(self):
return "I, %s, am being viewed" % (self)

def setEdit(self):
self.__str__ = self.__repr__ = self.Edit

def setView(self):
self.__str__ = self.__repr__ = self.View
....I would expect the following behavior:

In [130]: testObject = MyClass()
In [131]: testObject.setEdit()
In [132]: str(testObject)
Out[132]: 'I, <__main__.MyClass object at 0x511270>, am being edited'
Unfortunately, this is what happens instead:

In [130]: testObject = MyClass()
In [131]: testObject.setEdit()
In [132]: str(testObject)
Out[132]: '<__main__.MyClass object at 0x511270>'
In other words, str() is _NOT_ apparently calling <object>.__str__ as
it's supposed to! However, calling __str__ directly (which, yes,
you're not supposed to do) does work as expected:

In [133]: testObject.__str__()
Out[133]: 'I, <__main__.MyClass object at 0x511270>, am being edited'
Now, my understanding is that functions/methods are first-order
objects, and can be pointed to via reference, and that appears to be
true:

In [135]: def func1():
.....: print "I'm func1"
.....:
In [136]: def func2():
.....: print "I'm func2"
.....:
In [137]: func2 = func1
In [138]: func2()
I'm func1
However, expressions such as self.__str__ = <some function or method>
aren't working for me, as above. Why not?

Thanks for any responses,
Jeff

--
Jeffrey E. Forcier
Junior Developer, Research and Development
Stroz Friedberg, LLC
15 Maiden Lane, 12th Floor
New York, NY 10038
[main]212-981-6540 [direct]212-981-6546
http://www.strozllc.com

This message is for the named person's use only. It may contain
confidential, proprietary or legally privileged information. No right to
confidential or privileged treatment of this message is waived or lost
by any error in transmission. If you have received this message in
error, please immediately notify the sender by e-mail or by telephone at
212.981.6540, delete the message and all copies from your system and
destroy any hard copies. You must not, directly or indirectly, use,
disclose, distribute, print or copy any part of this message if you are
not the intended recipient.

Jul 22 '05 #1
7 1896
Jeffrey E. Forcier wrote:
In other words, str() is _NOT_ apparently calling <object>.__str__ as
it's supposed to! However, calling __str__ directly (which, yes, you're
not supposed to do) does work as expected:


I'm too tired and/or lazy to check, but I believe str() is calling
MyClass.__str__(testObject) as it is supposed to rather than
testObject.__str__() as you say it is supposed to. ;-)

Someone else or Google can probably enlighten you on the reason for this
better than I. I think this is something that is not explained very well
in the docs, which do say that a class implements special method names,
but doesn't make it very clear that an object can't always override them.

If you redirect to a second method you can overwrite on the instance, I
think you will get the results you want.
--
Michael Hoffman
Jul 23 '05 #2
On Jul 22, 2005, at 7:46 PM, Michael Hoffman wrote:
I'm too tired and/or lazy to check, but I believe str() is calling
MyClass.__str__(testObject) as it is supposed to rather than
testObject.__str__() as you say it is supposed to. ;-)

Someone else or Google can probably enlighten you on the reason for
this
better than I. I think this is something that is not explained very
well
in the docs, which do say that a class implements special method
names,
but doesn't make it very clear that an object can't always override
them.

If you redirect to a second method you can overwrite on the
instance, I
think you will get the results you want.
--
Michael Hoffman
--
http://mail.python.org/mailman/listinfo/python-list


So in other words, __str__() and its ilk are class methods instead of
instance methods? The documentation appears to contradict this:

(http://python.org/doc/2.4/ref/specialnames.html)
"For instance, if a class defines a method named __getitem__(), and x
is an instance of this class, then x[i] is equivalent to x.__getitem__
(i)."
However, you appear to be correct, and the docs appear to be confused:

class MyClass(object):

def edit(self):
return "I'm in edit mode"

def setToEdit(self):
MyClass.__str__ = self.edit

In [3]: test = MyClass()
In [4]: str(test)
Out[4]: '<__main__.MyClass object at 0x2d21d0>'
In [5]: test.setToEdit()
In [6]: str(test)
Out[6]: "I'm in edit mode"
Of course, this doesn't quite do what I had in mind, and in fact you
could say it's kinda sloppy, binding an ostensibly static class
method to an instance method:

In [7]: repr(MyClass.__str__)
Out[7]: '<bound method MyClass.edit of <__main__.MyClass object at
0x2d21d0>>'
Either way, guess I will have to take another route. Your suggestion
is what I'd had in mind, and does the job pretty well. I'm still
attempting to figure out the best approach to my overall problem,
however, so who knows where I will end up =)

Thanks for the response! If you or anyone else can shed some insight
on *why* this is the way it is (and why/if the docs are in fact
incorrect) I'd appreciate further replies. More knowledge == better.

Regards,
Jeff

--
Jeffrey E. Forcier
Junior Developer, Research and Development
Stroz Friedberg, LLC
15 Maiden Lane, 12th Floor
New York, NY 10038
[main]212-981-6540 [direct]212-981-6546
http://www.strozllc.com

This message is for the named person's use only. It may contain
confidential, proprietary or legally privileged information. No right to
confidential or privileged treatment of this message is waived or lost
by any error in transmission. If you have received this message in
error, please immediately notify the sender by e-mail or by telephone at
212.981.6540, delete the message and all copies from your system and
destroy any hard copies. You must not, directly or indirectly, use,
disclose, distribute, print or copy any part of this message if you are
not the intended recipient.

Jul 23 '05 #3
ncf
In trying to develop a protocol for a current app I'm working on, I was
using classes which inherited from object for my core packet, and using
str(Message) to convert it to an encoded packet. However, I found that
this did not work, and it drove me insane, so in a test file, I wrote
the following code:

class Whatever:
''' Supposed to be inheritable '''
def __init__(self):
self.__str__ = self._encode # Dynamically set the __str__ from
superclass(?)

Well, suffice to say, having the class not inherit from object solved
my problem, as I suspect it may solve yours. ;)

I havn't a clue why it acts that way, however, I hope knowledge of my
past experiances helps you also.

Have a GREAT day :)

-Wes

Jul 23 '05 #4
ncf wrote:
Well, suffice to say, having the class not inherit from object solved
my problem, as I suspect it may solve yours. ;)
Actually, I did a bit of experimenting. If the __str__ reassignment
worked as intended, it would just cause an infinite recursion.

To paste the class definition again: class MyClass(object):

def Edit(self):
return "I, %s, am being edited" % (self)

def View(self):
return "I, %s, am being viewed" % (self)

def setEdit(self):
self.__str__ = self.__repr__ = self.Edit

def setView(self):
self.__str__ = self.__repr__ = self.View


Notice the % (self) in Edit and View -- those recursively call
str(self), which causes infinite recursion.

In the spirit of getting the class working, though, the class-method
behavior of __str__ for new-style classes can be fixed with an extremely
ugly hack:
class MyClass(object):
def __init__(self):
self.__str__ = lambda : object.__str__(self)
def Edit(self):
return "I, %s, am being edited"

def View(self):
return "I, %s, am being viewed"

def setEdit(self):
self.__str__ = self.__repr__ = self.Edit

def setView(self):
self.__str__ = self.__repr__ = self.View
def __str__(self):
return self.__str__()

(Notice that I've removed the string substitution in Edit and View.
This also does not change the __repr__ method; it also acts as a class
method. But that's also easy enough to change in the same way.)

I also would be interested in knowing why new-style classes treat
__str__ as a class method.
Jul 23 '05 #5
Little less ugly:
In [12]:class A(object):
....: def __str__(self):return self.__str__()
....: def str(self):return 'ciao'
....: def setStr(self):self.__str__=self.str
....:

In [13]:a=A()

In [14]:a.setStr()

In [15]:str(a)
Out[15]:'ciao'

The point is str(ob) builtin looks like calling
ob.__class__.__str__(ob).Prolly Python-dev is the good place to ask about.



___________________________________
Yahoo! Mail: gratis 1GB per i messaggi e allegati da 10MB
http://mail.yahoo.it
Jul 23 '05 #6
Jeffrey E. Forcier wrote:
...
However, you appear to be correct, and the docs appear to be confused:
class MyClass(object):
def edit(self):
return "I'm in edit mode"
def setEdit(self):
MyClass.__str__ = self.edit
...
Either way, guess I will have to take another route. Your suggestion is
what I'd had in mind, and does the job pretty well. I'm still
attempting to figure out the best approach to my overall problem,
however, so who knows where I will end up =)


Here is one more standard way to do this:

class MyClass(object):
... # Common behavior goes here

def setEdit(self):
self.__class__ = MyEditClass

def setView(self):
self.__class__ = MyViewClass
class MyEditClass(MyClass):
def __repr__(self):
return "I, %s, am being edited" % super(
MyEditClass, self).__repr__()

class MyViewClass(MyClass):
def __repr__(self):
return "I, %s, am being viewed" % super(
MyViewClass, self).__repr__()
Be a little careful about the structure of the subclasses (MyViewClass
and MyEditClass) since they can wink into and out of existence, and
all will go well. Plus, you can easily override base behavior in the
subclasses differentially.

Note: for this example, you could also define the methods like:

class MyEditClass(MyClass):
def __repr__(self):
return "I, %s, am being edited" % MyClass.__repr__(self)

When to use super rather than direct access to the superclass is an
involved discussion.

--Scott David Daniels
Sc***********@Acm.Org
Jul 23 '05 #7
Paolino wrote:
Little less ugly:
In [12]:class A(object):
....: def __str__(self):return self.__str__()
....: def str(self):return 'ciao'
....: def setStr(self):self.__str__=self.str
....:

In [13]:a=A()

In [14]:a.setStr()

In [15]:str(a)
Out[15]:'ciao'


Not quite bug-free, by my eye that'll infintely recur if you call str(A()).
Jul 24 '05 #8

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

Similar topics

10
3034
by: Berthold Hoellmann | last post by:
Hello, When I use ./configure --with-thread --with-fpectl --with-signal-module \ --with-pymalloc --enable-shared --with-cxx=g++ make test on 2.3.3 I get
2
10256
by: francescomoi | last post by:
Hi. I'm trying to build 'MySQL-python-1.2.0' on my Linux FC2: ---------------------------------- # export PATH=$PATH:/usr/local/mysql/bin/ # export mysqlclient=mysqlclient_r # python setup.py...
53
4491
by: Alf P. Steinbach | last post by:
So, I got the itch to write something more... I apologize for not doing more on the attempted "Correct C++ Tutorial" earlier, but there were reasons. This is an UNFINISHED and RAW document,...
14
2805
by: Alf P. Steinbach | last post by:
Not yet perfect, but: http://home.no.net/dubjai/win32cpptut/special/pointers/ch_01.pdf http://home.no.net/dubjai/win32cpptut/special/pointers/ch_01_examples.zip To access the table of...
15
2082
by: Jiří Paleček | last post by:
Hello, I know the rules for const handling in C++, but I'd like to ask what is the "right" way to use them, eg. when is it appropriate to make a member function const? This came across this...
13
2365
by: Steve | last post by:
Hi; A friend of mine is publishing a book that includes 3000 citations, many with urls. When he made his bibliography he chopped off the "http://"s off of his urls. I wrote a program to...
1
4276
by: Ray | last post by:
Hello, I'm reading Mr. Flanagan's JS Definitive Guide 5th edition. I was wondering about a point he make in section 10.2 of the book: "Importing Symbols from Namespaces". He mentions in there...
8
2154
by: anon.asdf | last post by:
Hi! OK, lets try "array-copy": { char arrayA; arrayA = (char){1, 2, 3}; } it does *not* work since we're trying to make a fixed array-pointer arrayA, point to another location/address...
18
2430
by: Stephan Beal | last post by:
Hi, all! Before i ask my question, i want to clarify that my question is not about the code i will show, but about what the C Standard says should happen. A week or so ago it occurred to me...
0
7002
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7165
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7203
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...
1
6885
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...
0
7379
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...
0
5462
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 projectplanning, coding, testing,...
0
3093
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...
1
656
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
290
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...

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.