A library that can print Python objects in human readable format

Overview

objprint

build coverage pypi support-version license commit

A library that can print Python objects in human readable format

Install

pip install objprint

Usage

op

Use op() (or objprint()) to print objects.

from objprint import op

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

class Player:
    def __init__(self):
        self.name = "Alice"
        self.age = 18
        self.items = ["axe", "armor"]
        self.coins = {"gold": 1, "silver": 33, "bronze": 57}
        self.position = Position(3, 5)

op(Player())
<Player 0x7fe44e1e3070
  .age = 18,
  .coins = {'bronze': 57, 'gold': 1, 'silver': 33},
  .items = ['axe', 'armor'],
  .name = 'Alice',
  .position = <Position
    .x = 3,
    .y = 5
  >
>

You can print multiple objects just like print, except op will print them in separate lines

op([1, 2], {'a': 1})
[1, 2]
{'a': 1}

add_objprint

If you want to use print() to print your object, you can also use the class decorator add_objprint to add __str__ method for your class.

from objprint import add_objprint

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

@add_objprint
class Player:
    def __init__(self):
        self.name = "Alice"
        self.age = 18
        self.items = ["axe", "armor"]
        self.coins = {"gold": 1, "silver": 33, "bronze": 57}
        self.position = Position(3, 5)

# This will print the same thing as above
print(Player())

objstr

If you want the str representation of the object, instead of printing it on the screen, you can use objstr function

from objprint import objstr

s = objstr(my_object)

objjson

objprint supports print objects to json to make it easier to serialze an object.

objjson returns a jsonifiable object that can be dumped with json.dumps

from objprint import objjson

json_obj = objjson(Player())

print(json.dumps(json_obj, indent=2))
{
  ".type": "Player",
  "name": "Alice",
  "age": 18,
  "items": [
    "axe",
    "armor"
  ],
  "coins": {
    "gold": 1,
    "silver": 33,
    "bronze": 57
  },
  "position": {
    ".type": "Position",
    "x": 3,
    "y": 5
  }
}

You can use op to print in json format directly with format="json". You can pass in argument for json.dumps

op(Player(), format="json", indent=2)

add_objprint also works with format="json"

@add_objprint(format="json", indent=2)
class Player:
    pass

include/exclude attributes

You can include/exclude attributes using regular expression so objprint will only print out the attributes you are interested in.

op(Player(), include=["name"])
<Player
  .name = 'Alice'
>
op(Player(), exclude=[".*s"])
<Player 0x7fe44e1e3070
  .name = 'Alice',
  .age = 18,
  .position = <Position
    .x = 3,
    .y = 5
  >
>

If you specify both include and exclude, it will do a inclusive check first, then filter out the attributes that match exclusive check.

include and exclude arguments work on objprint, objstr and @add_objprint.

config

objprint formats the output based on some configs

  • config_name(default_value) - this config's explanation
  • depth(100) - how deep objprint goes into nested data structures
  • indent(2) - the indentation
  • width(80) - the maximum width a data structure will be presented as a single line
  • elements(-1) - the maximum number of elements that will be displayed, -1 means no restriction
  • color(True) - whether to use colored scheme
  • skip_recursion(True) - whether skip printing recursive data, which would cause infinite recursion without depth constraint
  • honor_existing(True) - whether to use the existing user defined __repr__ or __str__ method

You can set the configs globally using config function

from objprint import config

config(indent=4)

Or you can do a one time config by passing the arguments into objprint function

from objprint import op

op(var, indent=4)

install

Maybe you don't want to import op in every single file that you want to use. You can use install to make it globally accessible

from objprint import install

# Now you can use op() in any file
install()

# You can specify a name for objprint()
install("my_print")
my_print(my_object)

Bugs/Requests

Please send bug reports and feature requests through github issue tracker.

License

Copyright Tian Gao, 2020-2021.

Distributed under the terms of the Apache 2.0 license.

Comments
  • 在面对继承自pydantic里BaseModel的实例时无法得到预期的输出

    在面对继承自pydantic里BaseModel的实例时无法得到预期的输出

    如题

    from pydantic import BaseModel
    from objprint import op
    
    
    class pyt_class(BaseModel):
        x: int
        y: int
    
    
    obj_test = pyt_class(x=0, y=1)
    
    op(obj_test)
    print(obj_test)
    

    他打印:

    x=0 y=1
    x=0 y=1
    

    希望后续更新能够支持! (B站码农高天的视频我是期期都看,期期都三连)

    opened by Sclock 3
  • Also print the actual expression whose value is being printed

    Also print the actual expression whose value is being printed

    The https://github.com/gruns/icecream lib has an useful feature where it also prints the expression. Please see the following example:

    d = {'key': {1: 'one'}}
    ic(d['key'][1])
    
    class klass():
        attr = 'yep'
    ic(klass.attr)
    

    It prints:

    ic| d['key'][1]: 'one'
    ic| klass.attr: 'yep'
    

    As you can see icecream lib also prints the expression d['key'][1]. Is it possible to add this feature? This is the only feature holding me back from switching to objprint.

    opened by riyadparvez 3
  • Duplicate output when op() argument wasn't an object.

    Duplicate output when op() argument wasn't an object.

    import hashlib op(hashlib) <module 'hashlib' from 'C:\Users\guojoan\AppData\Local\Programs\Python\Python310\lib\hashlib.py'> <module 'hashlib' from 'C:\Users\guojoan\AppData\Local\Programs\Python\Python310\lib\hashlib.py'>

    a = [] a.append(a) op(a) [[ ... ]] [[...]]

    and so on

    opened by CokeStudios 2
  • type 类创建问题

    type 类创建问题

    通过type 构建的 class 通过 op 正确打印,这个feature 能否实现?

    from objprint import op
    
    class Action:
        pass
    
    def Category(label):
        return type("MCategory", (Action,), {"label": label,
                                            "__type__": "category"})
    
    
    class ECategory(Action):
        def __init__(self,label):
            self.label = label
            self.__type__ = 'category'
    
    
    
    mm = Category('test')
    nn = ECategory('test')
    op(mm)
    op(nn)
    
    >> <class '__main__.MCategory'>
    >> <UCategory 0x1f2da7b2b00
    >>   .label = 'test'
    >> >
    
    
    opened by wuqingjing2010 2
  • 如何实现“增量”打印?

    如何实现“增量”打印?

    您好!我正在使用objprint跟踪迭代过程,代码大致如下:

    for i in range(i_max):
        obj.step()
        op(obj)
    

    已知obj中有些变量在执行step后是不发生改变的,在第二次到最后一次调用op时,是否能够不打印这些变量?也就是只打印发生了变化的变量?

    opened by Saltsmart 2
  • weird escaped characters in jupyter notebook's output

    weird escaped characters in jupyter notebook's output

    I used pyreadstat module to read a simple SAS file. the code goes like this in jupyter notebook

    import pyreadstat as pyrs
    from objprint import op
    
    sas_path = './test_sas/foo.sas7bdat'
    df, meta = pyrs.read_sas7bdat(sas_path, metadataonly=True)
    # just wanted to check out what meta contains 
    op(meta)
    

    the brief output of current cell seems normal

    Output exceeds the [size limit]. Open the full output data[ in a text editor]
    <metadata_container 0x1bcf4bfa3e0
      .column_labels = [
        'projectid',
        'project',
    ...
        'project': '$'
      },
      .variable_value_labels = {}
    >
    <pyreadstat._readstat_parser.metadata_container at 0x1bcf4bfa3e0>
    

    but after I clicked "in a text editor", the first lines look like this:

    <metadata_container 0x1bcf4bfa3e0
      .column_labels = [
        'projectid',
        'project',
    

    the weird characters actually look like small suqares contains 3 small letters ESC in the text editor.

    opened by Asuralf 2
  • 在面对Enum对象时,输出的结果不符合预期。

    在面对Enum对象时,输出的结果不符合预期。

    测试代码:

    from enum import Enum
    from objprint import op,add_objprint
    
    class temp_a(Enum):
        a = 1
    
    @add_objprint
    class temp_b(Enum):
        b = 1
    
    print("temp_a:\n",temp_a,"\n")
    
    print("temp_a.a:\n",temp_a.a,"\n")
    
    print("op_temp_a:")
    op(temp_a)
    print("\n")
    
    print("op_temp_a.a:")
    op(temp_a.a)
    print("\n")
    
    print("================================================================\n")
    
    print("temp_b:\n",temp_b,"\n")
    
    print("temp_b.b:\n",temp_b.b,"\n")
    
    print("op_temp_b:")
    op(temp_b)
    print("\n")
    
    print("op_temp_b.b:")
    op(temp_b.b)
    print("\n")
    

    输出:

    temp_a:
     <enum 'temp_a'> 
    
    temp_a.a:
     temp_a.a
    
    op_temp_a:
    <enum 'temp_a'>
    
    
    op_temp_a.a:
    temp_a.a
    
    
    ================================================================
    
    temp_b:
     <enum 'temp_b'>
    
    temp_b.b:
     <temp_b 0x24a740c2ee0
      .__objclass__ = <enum 'temp_b'>,
      ._name_ = 'b',
      ._value_ = 1
    >
    
    op_temp_b:
    <enum 'temp_b'>
    
    
    op_temp_b.b:
    <temp_b 0x24a740c2ee0
      .__objclass__ = <enum 'temp_b'>,
      ._name_ = 'b',
      ._value_ = 1
    >
    

    符合直觉的结果应该是:

    class temp_a(Enum):
        a = 1
    op(temp_a)
    

    输出:

     <temp_a 0xFFFFFFFF
      .__objclass__ = <enum 'temp_a'>,
      .temp_a.a = < xxxxxxx
          ._name_ = 'b',
          ._value_ = 1
      >
    >
    
    opened by Sclock 2
  • 大佬,objprint可以打印出函数的内容吗?类似于js中console.log()方法。

    大佬,objprint可以打印出函数的内容吗?类似于js中console.log()方法。

    //JavaScript function ad(a, b) {

    return a + b;
    

    }

    console.log(ad.toString())

    //输出 // function ad(a, b) { // // return a + b; // }

    //python def ad(a,b): return a+b print(ad)

    输出

    <function ad at 0x000002511B318550>

    opened by xuxiaobo-bobo 1
  • Change the output order of line number and arg name

    Change the output order of line number and arg name

    For the following example:

    from objprint import config, install, objjson, op
    
    config(line_number=True)
    config(arg_name=True)
    
    x = 1
    op(x)
    

    This is the output right now:

    x:
    <module> (/path/to/objprint-test.py:7)
    1
    

    What I think more intuitive is argument name followed by the value and the file and line number at the top. In this particular case:

    <module> (/path/to/objprint-test.py:7)
    x:
    1
    

    Any thoughts?

    opened by riyadparvez 1
  • question: how to use install()

    question: how to use install()

    I created two python file to play with the install() feature:

    temp1.py:

    from objprint import op, install
    
    # Now you can use op() in any file
    install()
    

    temp2.py:

    op("hello")
    

    But run the temp2.py, it throws error : NameError: name 'op' is not defined What is the correct usage of install() ? Thanks !

    opened by wwdok 1
  • 在打印链表的时候结构不是很清晰

    在打印链表的时候结构不是很清晰

    打印链表会输出

    <Node 0x18136a4bd30
      .next = <Node 0x18136a4b3d0
        .next = <Node 0x18136dd5750
          .next = <Node 0x18136dd5930
            .next = <Node 0x18136dd5810
              .next = <Node 0x18136dd5870
                .next = None,
                .value = 'node_5'
              >,
              .value = 'node_4'
            >,
            .value = 'node_3'
          >,
          .value = 'node_2'
        >,
        .value = 'node_1'
      >,
      .value = 'Head'
    >
    

    可以考虑在打印属性为对象的属性的时候缩进幅度大一些

    <Node 0x18136a4bd30
        .next = <Node 0x18136a4b3d0
                .next = <Node 0x18136dd5750
                        .next = <Node 0x18136dd5930
                                    .next = <Node 0x18136dd5810
                                            .next = <Node 0x18136dd5870
                                                    .next = None,
                                                    .value = 'node_5'
                                            >,
                                            .value = 'node_4'
                                    >,
                                    .value = 'node_3'
                        >,
                        .value = 'node_2'
                >,
                .value = 'node_1'
         >,
         .value = 'Head'
    >
    

    或者结构修改一下

    <Node 0x18136a4bd30 ->  .next = <Node 0x18136a4b3d0 ->  .next = <Node 0x18136dd5750 ->  .next = <Node 0x18136dd5930 ->  .next = <Node 0x18136dd5810 ->  .next = <Node 0x18136dd5870 ->  .next = None,
                                                                                                                                                                                            .value = 'node_5'
                                                                                                                                                                                            >,         
                                                                                                                                                            .value = 'node_4'
                                                                                                                                                            >,
                                                                                                                            .value = 'node_3'
                                                                                                                            >,
                                                                                            .value = 'node_2'
                                                                                            >,
                                                            .value = 'node_1'
                                                            >,
                            .value = 'Head'
                            >
    

    简单的建议,希望能优化一下!

    opened by Sclock 1
  • pydantic.BaseModel 对象无法正确打印

    pydantic.BaseModel 对象无法正确打印

    我在使用 pydantic + objprint,打印对象使用了 #52 中的方法,但程序在 op 处阻塞住。

    from objprint import op
    from pydantic import BaseModel
    
    
    class A(BaseModel):
        a: int
    
    
    obj = A(a=1)
    op(obj, honor_existing=False)
    
    opened by Eric-fuyc 2
  • Detect repl for returning objects

    Detect repl for returning objects

    Now op() returns the object it prints to make calling chain possible. But in repl, that will print two instances. We should fix that for a better user experience.

    opened by gaogaotiantian 0
Releases(0.2.2)
Owner
Author of VizTracer, watchpoints and objprint
CountDown to New Year and shoot fireworks

CountDown and Shoot Fireworks About App This is an small application make you re

5 Dec 31, 2022
🏎️ Accelerate training and inference of 🤗 Transformers with easy to use hardware optimization tools

Hugging Face Optimum 🤗 Optimum is an extension of 🤗 Transformers, providing a set of performance optimization tools enabling maximum efficiency to t

Hugging Face 842 Dec 30, 2022
Classical OCR DCNN reproduction based on PaddlePaddle framework.

Paddle-SVHN Classical OCR DCNN reproduction based on PaddlePaddle framework. This project reproduces Multi-digit Number Recognition from Street View I

1 Nov 12, 2021
Code of the paper "Multi-Task Meta-Learning Modification with Stochastic Approximation".

Multi-Task Meta-Learning Modification with Stochastic Approximation This repository contains the code for the paper "Multi-Task Meta-Learning Modifica

Andrew 3 Jan 05, 2022
Official repository for the paper, MidiBERT-Piano: Large-scale Pre-training for Symbolic Music Understanding.

MidiBERT-Piano Authors: Yi-Hui (Sophia) Chou, I-Chun (Bronwin) Chen Introduction This is the official repository for the paper, MidiBERT-Piano: Large-

137 Dec 15, 2022
UA-GEC: Grammatical Error Correction and Fluency Corpus for the Ukrainian Language

UA-GEC: Grammatical Error Correction and Fluency Corpus for the Ukrainian Language This repository contains UA-GEC data and an accompanying Python lib

Grammarly 226 Dec 29, 2022
This is a TensorFlow implementation for C2-Rec

This is a TensorFlow implementation for C2-Rec We refer to the repo SASRec. Requirements requirement.txt Datasets This repo includes Amazon Beauty dat

7 Nov 14, 2022
Code for the SIGGRAPH 2021 paper "Consistent Depth of Moving Objects in Video".

Consistent Depth of Moving Objects in Video This repository contains training code for the SIGGRAPH 2021 paper "Consistent Depth of Moving Objects in

Google 203 Jan 05, 2023
Package for working with hypernetworks in PyTorch.

Package for working with hypernetworks in PyTorch.

Christian Henning 71 Jan 05, 2023
Implementation of the Swin Transformer in PyTorch.

Swin Transformer - PyTorch Implementation of the Swin Transformer architecture. This paper presents a new vision Transformer, called Swin Transformer,

597 Jan 03, 2023
Code for BMVC2021 "MOS: A Low Latency and Lightweight Framework for Face Detection, Landmark Localization, and Head Pose Estimation"

MOS-Multi-Task-Face-Detect Introduction This repo is the official implementation of "MOS: A Low Latency and Lightweight Framework for Face Detection,

104 Dec 08, 2022
Implementation of UNET architecture for Image Segmentation.

Semantic Segmentation using UNET This is the implementation of UNET on Carvana Image Masking Kaggle Challenge About the Dataset This dataset contains

Anushka agarwal 4 Dec 21, 2021
Implementation for paper "Towards the Generalization of Contrastive Self-Supervised Learning"

Contrastive Self-Supervised Learning on CIFAR-10 Paper "Towards the Generalization of Contrastive Self-Supervised Learning", Weiran Huang, Mingyang Yi

Weiran Huang 13 Nov 30, 2022
PyTorch implementation of Deformable Convolution

Deformable Convolutional Networks in PyTorch This repo is an implementation of Deformable Convolution. Ported from author's MXNet implementation. Buil

411 Dec 16, 2022
CBKH: The Cornell Biomedical Knowledge Hub

Cornell Biomedical Knowledge Hub (CBKH) CBKG integrates data from 18 publicly available biomedical databases. The current version of CBKG contains a t

44 Dec 21, 2022
Tensorflow Tutorials using Jupyter Notebook

Tensorflow Tutorials using Jupyter Notebook TensorFlow tutorials written in Python (of course) with Jupyter Notebook. Tried to explain as kindly as po

Sungjoon 2.6k Dec 22, 2022
Answer a series of contextually-dependent questions like they may occur in natural human-to-human conversations.

SCAI-QReCC-21 [leaderboards] [registration] [forum] [contact] [SCAI] Answer a series of contextually-dependent questions like they may occur in natura

19 Sep 28, 2022
Code for the paper "VisualBERT: A Simple and Performant Baseline for Vision and Language"

This repository contains code for the following two papers: VisualBERT: A Simple and Performant Baseline for Vision and Language (arxiv) with a short

Natural Language Processing @UCLA 463 Dec 09, 2022
Peek-a-Boo: What (More) is Disguised in a Randomly Weighted Neural Network, and How to Find It Efficiently

Peek-a-Boo: What (More) is Disguised in a Randomly Weighted Neural Network, and How to Find It Efficiently This repository is the official implementat

VITA 4 Dec 20, 2022
UMPNet: Universal Manipulation Policy Network for Articulated Objects

UMPNet: Universal Manipulation Policy Network for Articulated Objects Zhenjia Xu, Zhanpeng He, Shuran Song Columbia University Robotics and Automation

Columbia Artificial Intelligence and Robotics Lab 33 Dec 03, 2022