object dumper class
The object dumper posted in sgmoore's link:
//Copyright (C) Microsoft Corporation. All rights reserved.
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
// See the ReadMe.html for additional information
public class ObjectDumper {
public static void Write(object element)
{
Write(element, 0);
}
public static void Write(object element, int depth)
{
Write(element, depth, Console.Out);
}
public static void Write(object element, int depth, TextWriter log)
{
ObjectDumper dumper = new ObjectDumper(depth);
dumper.writer = log;
dumper.WriteObject(null, element);
}
TextWriter writer;
int pos;
int level;
int depth;
private ObjectDumper(int depth)
{
this.depth = depth;
}
private void Write(string s)
{
if (s != null) {
writer.Write(s);
pos += s.Length;
}
}
private void WriteIndent()
{
for (int i = 0; i < level; i++) writer.Write(" ");
}
private void WriteLine()
{
writer.WriteLine();
pos = 0;
}
private void WriteTab()
{
Write(" ");
while (pos % 8 != 0) Write(" ");
}
private void WriteObject(string prefix, object element)
{
if (element == null || element is ValueType || element is string) {
WriteIndent();
Write(prefix);
WriteValue(element);
WriteLine();
}
else {
IEnumerable enumerableElement = element as IEnumerable;
if (enumerableElement != null) {
foreach (object item in enumerableElement) {
if (item is IEnumerable && !(item is string)) {
WriteIndent();
Write(prefix);
Write("...");
WriteLine();
if (level < depth) {
level++;
WriteObject(prefix, item);
level--;
}
}
else {
WriteObject(prefix, item);
}
}
}
else {
MemberInfo[] members = element.GetType().GetMembers(BindingFlags.Public | BindingFlags.Instance);
WriteIndent();
Write(prefix);
bool propWritten = false;
foreach (MemberInfo m in members) {
FieldInfo f = m as FieldInfo;
PropertyInfo p = m as PropertyInfo;
if (f != null || p != null) {
if (propWritten) {
WriteTab();
}
else {
propWritten = true;
}
Write(m.Name);
Write("=");
Type t = f != null ? f.FieldType : p.PropertyType;
if (t.IsValueType || t == typeof(string)) {
WriteValue(f != null ? f.GetValue(element) : p.GetValue(element, null));
}
else {
if (typeof(IEnumerable).IsAssignableFrom(t)) {
Write("...");
}
else {
Write("{ }");
}
}
}
}
if (propWritten) WriteLine();
if (level < depth) {
foreach (MemberInfo m in members) {
FieldInfo f = m as FieldInfo;
PropertyInfo p = m as PropertyInfo;
if (f != null || p != null) {
Type t = f != null ? f.FieldType : p.PropertyType;
if (!(t.IsValueType || t == typeof(string))) {
object value = f != null ? f.GetValue(element) : p.GetValue(element, null);
if (value != null) {
level++;
WriteObject(m.Name + ": ", value);
level--;
}
}
}
}
}
}
}
}
private void WriteValue(object o)
{
if (o == null) {
Write("null");
}
else if (o is DateTime) {
Write(((DateTime)o).ToShortDateString());
}
else if (o is ValueType || o is string) {
Write(o.ToString());
}
else if (o is IEnumerable) {
Write("...");
}
else {
Write("{ }");
}
}
}
2015 Update
YAML also serves this purpose quite well, this is how it can be done with YamlDotNet
install-package YamlDotNet
private static void DumpAsYaml(object o)
{
var stringBuilder = new StringBuilder();
var serializer = new Serializer();
serializer.Serialize(new IndentedTextWriter(new StringWriter(stringBuilder)), o);
Console.WriteLine(stringBuilder);
}
What is the best way to dump entire objects to a log in C#?
You could base something on the ObjectDumper code that ships with the Linq samples.
Have also a look at the answer of this related question to get a sample.
Dumping a java object's properties
You could try XStream.
XStream xstream = new XStream(new Sun14ReflectionProvider(
new FieldDictionary(new ImmutableFieldKeySorter())),
new DomDriver("utf-8"));
System.out.println(xstream.toXML(new Outer()));
prints out:
<foo.ToString_-Outer>
<intValue>5</intValue>
<innerValue>
<stringValue>foo</stringValue>
</innerValue>
</foo.ToString_-Outer>
You could also output in JSON
And be careful of circular references ;)
Pickle Dump to save an object within the class
You can pass self
instead of obj
. In other words:
def save(self, file_handler):
pickle.dump(self, file_handler)
The self
points to the instance of that class. So what you basically do is calling pickle.dump
and passing the instance to it together with the file_handler
argument.
How to dump user defined python objects to json file? By Objects I mean actual objects and not their attributes
Use pickle.
It will not be human readable and not in json format. But this module is intended to store Python objects and load it back again in future.
See more this for comparison with json
module.
dump an python object as yaml file
You need to implement __repr__ for the class. You could just use your __str__ as __repr__.
YAML - Dumping a nested object without types/tags
Although the words "correct YAML" are not really accurate, and would be better phrased as
"YAML output looking like you want it, except for the tag information", this fortunately gives some
information on how you want your YAML to look, as there are an infinite number of ways to dump objects.
If you dump an object using ruamel.yaml
:
import sys
import ruamel.yaml
class MyObject:
def __init__(self, a, b):
self.a = a
self.b = b
self.c = [a, b]
data = dict(x=MyObject(42, -1))
yaml = ruamel.yaml.YAML(typ='unsafe')
yaml.dump(data, sys.stdout)
this gives:
x: !!python/object:__main__.MyObject
a: 42
b: -1
c: [42, -1]
You have a tag !!python/object:__main__.MyObject
(yours might differ depending on where the
class is defined, etc.) and each of the attributes of the class are dumped as keys of a mapping.
There are multiple ways on how to get rid of the tag in that dump:
Registering classes
Add a classmethod
named to_yaml()
, to each of your classes and
register those classes. You have to do this for each of your classes,
but doing so allows you to use the safe-dumper. An example on how to
do this can be found in the
documentation
Post-process
It is fairly easy to postprocess the output and remove the tags, which for objects always occur on the line
before the mapping, and you can delete from !!python
until the end-of-line
def strip_python_tags(s):
result = []
for line in s.splitlines():
idx = line.find("!!python/")
if idx > -1:
line = line[:idx]
result.append(line)
return '\n'.join(result)
yaml.encoding = None
yaml.dump(data, sys.stdout, transform=strip_python_tags)
and that gives:
x:
a: 42
b: -1
c: [42, -1]
As achors are dumped before the tag, this "stripping from !!python
until end-of-the line", also works when you dump object that have
multiple references.
Change the dumper
You can also change the unsafe dumper routine for mappings to
recognise the tag used for objects and change the tag to the "normal"
one for dict/mapping (for which normally a tag is not output )
yaml.representer.org_represent_mapping = yaml.representer.represent_mapping
def my_represent_mapping(tag, mapping, flow_style=None):
if tag.startswith("tag:yaml.org,2002:python/object"):
tag = u'tag:yaml.org,2002:map'
return yaml.representer.org_represent_mapping(tag, mapping, flow_style=flow_style)
yaml.representer.represent_mapping = my_represent_mapping
yaml.dump(data, sys.stdout)
and that gives once more:
x:
a: 42
b: -1
c: [42, -1]
These last two methods work for all instances of all Python classes that you define without extra work.
Related Topics
How to Find the State of Numlock, Capslock and Scrolllock in .Net
Modify Struct Variable in a Dictionary
Should I Store My Images in the Database or Folders
Why Func<T,Bool> Instead of Predicate<T>
Httpwebrequest Is Extremely Slow!
Check If Instance Is of a Type
Check If the Current User Is Administrator
Winforms | C# | Autocomplete in the Middle of a Textbox
Graphics.Drawstring VS Textrenderer.Drawtextwhich Can Deliver Better Quality
What Is the "Right" Way to Bring a Windows Forms Application to the Foreground
Passing Object in Redirecttoaction
Print Webbrowser Without Previewing I.E. Single Click Print
What's the Difference Between Iequatable and Just Overriding Object.Equals()
Save and Retrieve Image (Binary) from SQL Server Using Entity Framework 6
How to Provide Custom Cast Support for My Class