Can print() be reloaded for a user defined class?

P

Peng Yu

Hi,

I have the following code. The last line does not print the members
("x" and "y") of 'my_bin'. I am wondering if there is a way to reload
the print function for bin, so that the last line print the members of
'my_bin'.

Regards,
Peng

class bin:
def __init__(self, x, y) :
self.x = x
self.y = y

if __name__ == '__main__':

my_bin = bin(1, 2)
print my_bin
 
R

r

Hi,

I have the following code. The last line does not print the members
("x" and "y") of 'my_bin'. I am wondering if there is a way to reload
the print function for bin, so that the last line print the members of
'my_bin'.

Regards,
Peng

class bin:
  def __init__(self, x, y) :
    self.x = x
    self.y = y

if __name__ == '__main__':

  my_bin = bin(1, 2)
  print my_bin

use the __str__ and or __repr__ methods
class Bin:
def __init__(self, x, y) :
self.x = x
self.y = y
def __str__(self):
return 'Bin(%s, %s)' %(self.x, self.y)
__repr__ = __str__

Please use an initial capital letter when defining a class, this is
the accepted way in many languages!!!
 
P

Peng Yu

use the __str__ and or __repr__ methods


    def __str__(self):
        return 'Bin(%s, %s)' %(self.x, self.y)
    __repr__ = __str__

Please use an initial capital letter when defining a class, this is
the accepted way in many languages!!!

I want to understand the exact meaning of the last line ('__repr__ =
__str__'). Would you please point me to the section of the python
manual that describes such usage.

Regards,
Peng
 
R

r

I want to understand the exact meaning of the last line ('__repr__ =
__str__'). Would you please point me to the section of the python
manual that describes such usage.

simple i assined any call to __repr__ to the __str__ methods.


def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return 'Test(%s, %s)' %(self.x, self.y)

def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return 'Test(%s, %s)' %(self.x, self.y)
__repr__ = __str__

'Test(3, 4)'

it's good for command line testing since you will not need to call
print < instance > all the time. You may not always want to use this
binding of __repr__ to __str__, but it has some effective uses ;)
 
D

Dave Angel

Peng said:
I want to understand the exact meaning of the last line ('__repr__ __str__'). Would you please point me to the section of the python
manual that describes such usage.

Regards,
Peng
I don't know where to look in the various manuals, but what we have here
are class attributes. Inside the class definition, each method
definition is a class attribute. In addition, any "variable" definition
is a class attribute as well. For example,
class MyClass(object):
counter = 0
def __str__(self):
return "Kilroy"+str(self.value)
def __init__(self, num):
self.value = num+1

counter is a class attribute, initialized to zero. That attribute is
shared among all the instances, unlike data attributes, which are
independently stored in each instance.

Anyway, the __repr__ = __str__ simply copies a class attribute. So
now you have two names which call the same method. To explicitly call
one of them, you might use:


obj = MyClass(42)
mystring = obj.__str__() #mystring is now "Kilroy43"


But normally, you don't directly call such methods, except for debug
purposes. They are implicitly called by functions like print().
 
P

Peng Yu

I don't know where to look in the various manuals, but what we have here are
class attributes.  Inside the class definition, each method definition is a
class attribute.  In addition, any "variable" definition is a class
attribute as well.  For example,
 class  MyClass(object):
      counter = 0
      def __str__(self):
            return "Kilroy"+str(self.value)
      def __init__(self, num):
            self.value = num+1

counter is a class attribute, initialized to zero.  That attribute is shared
among all the instances, unlike data attributes, which are independently
stored in each instance.

Anyway, the   __repr__ = __str__   simply copies a class attribute.  So now
you have two names which call the same method.  To explicitly call one of
them, you might use:

Is __repr__ = __str__ copy by reference or by value? If I change
__str__ later on, will __repr__ be changed automatically?

Regards,
Peng
 
A

alex23

Peng Yu said:
Is __repr__ = __str__ copy by reference or by value? If I change
__str__ later on, will __repr__ be changed automatically?

What would you expect the outcome to be if these were functions rather
than class methods? (Or any type of object, really...)

Wouldn't it be quicker (and certainly less spammy) to test this out in
the interpreter?
 
D

Dave Angel

Peng said:
Is __repr__ =_str__ copy by reference or by value? If I change
__str__ later on, will __repr__ be changed automatically?

Regards,
Peng
Reference or value? Neither one. This assignment is no different than
any other attribute assignment in Python. Technically, it binds the
name __repr__ to the function object already bound by __str__. You now
have a second name pointing to the same object. Rebinding one of those
names to yet another different object won't affect the other name.

name1 = "this is a test"
name2 = name1
name1 = "another string" #this has no effect on name2

print name1, name2

DaveA
 
P

Peng Yu

Reference or value?  Neither one.  This assignment is no different than any
other attribute assignment in Python.  Technically, it binds the name
__repr__ to the function object already bound by __str__.  You now have a
second name pointing to the same object.  Rebinding one of those names  to
yet another different object won't affect the other name.

name1 = "this is a test"
name2 = name1
name1 = "another string"           #this has no effect on name2

print name1, name2

I am more familiar with C++ than python. So I need to connect python
concept to C++ concept so that I can understand it better.

name1 and name are all references (in the C++ sense), right?

__repr__ and __str__ are references (in the C++ sense) to functions
and both of them could refer to the same function or two different
ones, right?

Regards,
Peng
 
R

r

I am more familiar with C++ than python. So I need to connect python
concept to C++ concept so that I can understand it better.

name1 and name are all references (in the C++ sense), right?

__repr__  and __str__ are references (in the C++ sense) to functions
and both of them could refer to the same function or two different
ones, right?

Don't ever try and map C++ to Python on a 1:1 basis or you will get
quite confused. Try this thought experiment, and remember, the Python
shell is your best friend now!

IDLE 2.6.2Help on built-in function id in module __builtin__:

id(...)
id(object) -> integer

Return the identity of an object. This is guaranteed to be unique
among
simultaneously existing objects. (Hint: it's the object's memory
address.)


NOW you can apply that logic 1:1 to your python problem ;-)
 
B

Benjamin Kaplan

I am more familiar with C++ than python. So I need to connect python
concept to C++ concept so that I can understand it better.

name1 and name are all references (in the C++ sense), right?

__repr__  and __str__ are references (in the C++ sense) to functions
and both of them could refer to the same function or two different
ones, right?

Sort of, but it would be best to forget about the C++ ideas of
references and values because it will only confuse you. In python,
everything is an object and every attribute is stored as a dict key,
including functions. When you do __repr__ = __str__, you are making
the name '__repr__' refer to the same object as the name '__str__'.
Since they are the same object, any mutations made to one object will
appear in the other. However, a reassignment does not change the value
of the object, it just makes that key refer to another object. So if
you were to later change __str__ to a different method, __repr__
wouldn't change.
 
D

Dave Angel

Peng said:
I am more familiar with C++ than python. So I need to connect python
concept to C++ concept so that I can understand it better.

name1 and name are all references (in the C++ sense), right?

__repr__ and __str__ are references (in the C++ sense) to functions
and both of them could refer to the same function or two different
ones, right?

Regards,
Peng
By limiting yourself to C++ terminology, you're restricting how well you
can understand it. But I'll try.

C++ references cannot change. And C++ functions cannot be created on
the fly. But otherwise, these names work kinda like C++ references.

Perhaps it'd help if I try to describe how some of this stuff works.
For now, let's skip classes entirely, and just deal with top-level stuff
(global scope).

Let's say we're in a module called mymodule.py. So there's an object
called mymodule, with a dictionary in it containing some attributes
This dictionary works just like any dictionary you might define, but
it's "under the covers," so to speak. You add stuff to this dictionary
by doing an "assignment."

name1= "value"

creates a new string object, and adds a dictionary item with key of
"name1" and value of pointer-to-the-string-object

name2 = 42

does the same thing, but it's an int object.

name1 = name2 doesn't create a new dictionary item, since it's already
there. But it changes the value of the item from ptr-to-int to
ptr-to-string. At this point, the string object doesn't have any refs,
so it probably gets freed. And the int object has two refs. It doesn't
know what they are, just that the count is two.

def myfunct():
return 12

creates a code object, and adds a dictionary item with key of "myfunct"
and value of pointer-to-the-code-object.

otherfunct = myfunct creates a new dictionary item with the same value
as the existing one. And ref count goes to two.

Notice that there's nothing stopping you from doing

name1 = myfunct

and now name1 acts like a function, instead of a string or an int. All
these things are first-class objects.

One more piece for today's lesson:

import othermodule

This creates an entry in our module dictionary with key of "othermodule"
and value pointing to the imported module.

Now, we can get at our own symbols by name1, or name2. And we can get
at symbols from othermodule by othermodule.name3

This simply finds othermodule in the current global dictionary, then
looks up name3 in that othermodule's dictionary.

Clearer ?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,179
Messages
2,570,956
Members
47,509
Latest member
Jack116

Latest Threads

Top