Example Needed: Change the default print method of an object
Here's an example to get you started. Once you get the basic idea of how S3 methods are dispatched, have a look at any of the print methods returned by methods("print")
to see how you can achieve more interesting print styles.
## Define a print method that will be automatically dispatched when print()
## is called on an object of class "myMatrix"
print.myMatrix <- function(x) {
n <- nrow(x)
for(i in seq_len(n)) {
cat(paste("This is row", i, "\t: " ))
cat(x[i,], "\n")
}
}
## Make a couple of example matrices
m <- mm <- matrix(1:16, ncol=4)
## Create an object of class "myMatrix".
class(m) <- c("myMatrix", class(m))
## When typed at the command-line, the 'print' part of the read-eval-print loop
## will look at the object's class, and say "hey, I've got a method for you!"
m
# This is row 1 : 1 5 9 13
# This is row 2 : 2 6 10 14
# This is row 3 : 3 7 11 15
# This is row 4 : 4 8 12 16
## Alternatively, you can specify the print method yourself.
print.myMatrix(mm)
# This is row 1 : 1 5 9 13
# This is row 2 : 2 6 10 14
# This is row 3 : 3 7 11 15
# This is row 4 : 4 8 12 16
How to print instances of a class using print()?
>>> class Test:
... def __repr__(self):
... return "Test()"
... def __str__(self):
... return "member of Test"
...
>>> t = Test()
>>> t
Test()
>>> print(t)
member of Test
The __str__
method is what gets called happens when you print it, and the __repr__
method is what happens when you use the repr()
function (or when you look at it with the interactive prompt).
If no __str__
method is given, Python will print the result of __repr__
instead. If you define __str__
but not __repr__
, Python will use what you see above as the __repr__
, but still use __str__
for printing.
How to create a println/print method for a custom class
You will need to override the toString
method and return a string representation of what you want.
So for example:
public class Pair {
Object key;
Object value;
public Pair(Object k, Object v)
{
key = k;
value = v;
}
public Object getKey() {
return key;
}
public Object getValue() {
return value;
}
public String toString() {
return "Key: " + getKey() + ", Value: " + getValue();
}
}
Than you can do the following:
List<Pair> pairs = new ArrayList<Pair>();
pairs.Add(new Pair("pair1key", "pair1value"));
pairs.Add(new Pair("pair2key", "pair2value"));
for (Pair p : pairs) {
System.out.println(p);
}
How do I print my Java object without getting SomeType@2f92e0f4 ?
Background
All Java objects have a toString()
method, which is invoked when you try to print the object.
System.out.println(myObject); // invokes myObject.toString()
This method is defined in the Object
class (the superclass of all Java objects). The Object.toString()
method returns a fairly ugly looking string, composed of the name of the class, an @
symbol and the hashcode of the object in hexadecimal. The code for this looks like:
// Code of Object.toString()
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
A result such as com.foo.MyType@2f92e0f4
can therefore be explained as:
com.foo.MyType
- the name of the class, i.e. the class isMyType
in the packagecom.foo
.@
- joins the string together2f92e0f4
the hashcode of the object.
The name of array classes look a little different, which is explained well in the Javadocs for Class.getName()
. For instance, [Ljava.lang.String
means:
[
- an single-dimensional array (as opposed to[[
or[[[
etc.)L
- the array contains a class or interfacejava.lang.String
- the type of objects in the array
Customizing the Output
To print something different when you call System.out.println(myObject)
, you must override the toString()
method in your own class. Here's a simple example:
public class Person {
private String name;
// constructors and other methods omitted
@Override
public String toString() {
return name;
}
}
Now if we print a Person
, we see their name rather than com.foo.Person@12345678
.
Bear in mind that toString()
is just one way for an object to be converted to a string. Typically this output should fully describe your object in a clear and concise manner. A better toString()
for our Person
class might be:
@Override
public String toString() {
return getClass().getSimpleName() + "[name=" + name + "]";
}
Which would print, e.g., Person[name=Henry]
. That's a really useful piece of data for debugging/testing.
If you want to focus on just one aspect of your object or include a lot of jazzy formatting, you might be better to define a separate method instead, e.g. String toElegantReport() {...}
.
Auto-generating the Output
Many IDEs offer support for auto-generating a toString()
method, based on the fields in the class. See docs for Eclipse and IntelliJ, for example.
Several popular Java libraries offer this feature as well. Some examples include:
ToStringBuilder
from Apache Commons LangMoreObjects.ToStringHelper
from Google Guava@ToString
annotation from Project Lombok
Printing groups of objects
So you've created a nice toString()
for your class. What happens if that class is placed into an array or a collection?
Arrays
If you have an array of objects, you can call Arrays.toString()
to produce a simple representation of the contents of the array. For instance, consider this array of Person
objects:
Person[] people = { new Person("Fred"), new Person("Mike") };
System.out.println(Arrays.toString(people));
// Prints: [Fred, Mike]
Note: this is a call to a static method called toString()
in the Arrays class, which is different to what we've been discussing above.
If you have a multi-dimensional array, you can use Arrays.deepToString()
to achieve the same sort of output.
Collections
Most collections will produce a pretty output based on calling .toString()
on every element.
List<Person> people = new ArrayList<>();
people.add(new Person("Alice"));
people.add(new Person("Bob"));
System.out.println(people);
// Prints [Alice, Bob]
So you just need to ensure your list elements define a nice toString()
as discussed above.
What is the default print method of a class when called in a console?
For print x
, x.__str__
is called.
For output in a REPL when an object is returned, x.__repr__
is called.
Read about str
and repr
functions.
Is there a built-in function to print all the current properties and values of an object?
You are really mixing together two different things.
Use dir()
, vars()
or the inspect
module to get what you are interested in (I use __builtins__
as an example; you can use any object instead).
>>> l = dir(__builtins__)
>>> d = __builtins__.__dict__
Print that dictionary however fancy you like:
>>> print l
['ArithmeticError', 'AssertionError', 'AttributeError',...
or
>>> from pprint import pprint
>>> pprint(l)
['ArithmeticError',
'AssertionError',
'AttributeError',
'BaseException',
'DeprecationWarning',
...
>>> pprint(d, indent=2)
{ 'ArithmeticError': <type 'exceptions.ArithmeticError'>,
'AssertionError': <type 'exceptions.AssertionError'>,
'AttributeError': <type 'exceptions.AttributeError'>,
...
'_': [ 'ArithmeticError',
'AssertionError',
'AttributeError',
'BaseException',
'DeprecationWarning',
...
Pretty printing is also available in the interactive debugger as a command:
(Pdb) pp vars()
{'__builtins__': {'ArithmeticError': <type 'exceptions.ArithmeticError'>,
'AssertionError': <type 'exceptions.AssertionError'>,
'AttributeError': <type 'exceptions.AttributeError'>,
'BaseException': <type 'exceptions.BaseException'>,
'BufferError': <type 'exceptions.BufferError'>,
...
'zip': <built-in function zip>},
'__file__': 'pass.py',
'__name__': '__main__'}
Can I change the default __add__ method in Python?
If you are looking for information about how the C level built-ins are defined you would want to look at some of the source code, note that I'm linking specifically to floats but the structure exists for all number types:
static PyNumberMethods float_as_number = {
float_add, /* nb_add */
float_sub, /* nb_subtract */
float_mul, /* nb_multiply */
this is the structure for all the C function pointers that implement number methods, (for floats in this case) each builtin type that defines any number related methods will define a PyNumberMethods
structure, this is then used in the formal definition of the type:
PyTypeObject PyFloat_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"float",
sizeof(PyFloatObject),
...
&float_as_number, /* tp_as_number */
the PyTypeObject
represents all the relevant information needed to construct the float
object in python, (or equivalently, int
or str
etc.) containing all the methods, attributes, and necessary meta-data to work as a python type. So if you really wanted to change adding floats to instead do another well defined task you'd just change it to point to the other function:
static PyNumberMethods float_as_number = {
float_sub, /* nb_add. overrides to do subtraction because I want to break everything >:D */
float_sub, /* nb_subtract */
If you wanted to write your own behaviour you could write your own function and point to it in this structure instead.
Can I replace an existing method of an object in Python?
Using some tips from:
Is it possible to change an instance's method implementation without changing all other instances of the same class?
you can do the following, by using the types module to assign a method to the object created without affecting the class. You need to do this because a function does not automatically receive the self object as the first variable, but a method does.
import types
joe = Person()
bob = Person()
joe.SayHi()
>>> Hello!
def greedy_has_good_mood(self):
return self.Cash > 100
joe.HasGoodMood = types.MethodType(greedy_has_good_mood, joe)
joe.SayHi()
>>> Hmpf.
bob.SayHi()
>>> Hello!
custom print statement for python function objects
Few errors:
>>> def f():
... pass
...
>>> g = f() <---- g is the return value of running f
>>> print g
None
in the first case, when you call print, you are calling a string representation of f
>>> f = F()
>>> print f <----- f is an instance of class F and
<----- print f tries to provide a suitable string representation
<----- by calling f.__str__
You should use doc strings for your motives
>>> def f():
... " some doc"
... pass
...
>>>
>>> f.__doc__
' some doc'
>>>
What you are trying to do is override the method wrapper __str__
.
>>> def f():
... "some documentation .."
... pass
...
>>>
>>> f.__str__
<method-wrapper '__str__' of function object at 0x100430140>
>>>
Related Topics
Change Colours of Particular Bars in a Bar Chart
How to Cross-Paste All Combinations of Two Vectors (Each-To-Each)
How to Detect Free Variable Names in R Functions
How to Suppress the Creation of a Plot While Calling a Function in R
Package Rgl in R Not Loading in MAC Os
Roc Curve from Training Data in Caret
Solving Simultaneous Equations with R
R: Merge Two Irregular Time Series
How to Resolve Spherical Geometry Failures When Joining Spatial Data
Edit Datatable in Shiny with Dropdown Selection for Factor Variables
Reshaping Data Frame with Duplicates
How to Get a Second Bibliography
Create Binary Column (0/1) Based on Condition in Another Column