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
Implementation of a protein autoregressive language model, but with autoregressive infilling objective (editing subsequences capability)

Protein GLM (wip) Implementation of a protein autoregressive language model, but with autoregressive infilling objective (editing subsequences capabil

Phil Wang 17 May 06, 2022
Face Detection and Alignment using Multi-task Cascaded Convolutional Networks (MTCNN)

Face-Detection-with-MTCNN Face detection is a computer vision problem that involves finding faces in photos. It is a trivial problem for humans to sol

Chetan Hirapara 3 Oct 07, 2022
This is an official implementation for "Swin Transformer: Hierarchical Vision Transformer using Shifted Windows" on Object Detection and Instance Segmentation.

Swin Transformer for Object Detection This repo contains the supported code and configuration files to reproduce object detection results of Swin Tran

Swin Transformer 1.4k Dec 30, 2022
PyTorch implementation of SmoothGrad: removing noise by adding noise.

SmoothGrad implementation in PyTorch PyTorch implementation of SmoothGrad: removing noise by adding noise. Vanilla Gradients SmoothGrad Guided backpro

SSKH 143 Jan 05, 2023
Styled Handwritten Text Generation with Transformers (ICCV 21)

⚡ Handwriting Transformers [PDF] Ankan Kumar Bhunia, Salman Khan, Hisham Cholakkal, Rao Muhammad Anwer, Fahad Shahbaz Khan & Mubarak Shah Abstract: We

Ankan Kumar Bhunia 85 Dec 22, 2022
Point Cloud Registration Network

PCRNet: Point Cloud Registration Network using PointNet Encoding Source Code Author: Vinit Sarode and Xueqian Li Paper | Website | Video | Pytorch Imp

ViNiT SaRoDe 59 Nov 19, 2022
"Learning and Analyzing Generation Order for Undirected Sequence Models" in Findings of EMNLP, 2021

undirected-generation-dev This repo contains the source code of the models described in the following paper "Learning and Analyzing Generation Order f

Yichen Jiang 0 Mar 25, 2022
Unofficial pytorch implementation for Self-critical Sequence Training for Image Captioning. and others.

An Image Captioning codebase This is a codebase for image captioning research. It supports: Self critical training from Self-critical Sequence Trainin

Ruotian(RT) Luo 906 Jan 03, 2023
TensorFlow implementation of the algorithm in the paper "Decoupled Low-light Image Enhancement"

Decoupled Low-light Image Enhancement Shijie Hao1,2*, Xu Han1,2, Yanrong Guo1,2 & Meng Wang1,2 1Key Laboratory of Knowledge Engineering with Big Data

17 Apr 25, 2022
Answering Open-Domain Questions of Varying Reasoning Steps from Text

This repository contains the authors' implementation of the Iterative Retriever, Reader, and Reranker (IRRR) model in the EMNLP 2021 paper "Answering Open-Domain Questions of Varying Reasoning Steps

26 Dec 22, 2022
Monk is a low code Deep Learning tool and a unified wrapper for Computer Vision.

Monk - A computer vision toolkit for everyone Why use Monk Issue: Want to begin learning computer vision Solution: Start with Monk's hands-on study ro

Tessellate Imaging 507 Dec 04, 2022
Riemannian Geometry for Molecular Surface Approximation (RGMolSA)

Riemannian Geometry for Molecular Surface Approximation (RGMolSA) Introduction Ligand-based virtual screening aims to reduce the cost and duration of

11 Nov 15, 2022
FocusFace: Multi-task Contrastive Learning for Masked Face Recognition

FocusFace This is the official repository of "FocusFace: Multi-task Contrastive Learning for Masked Face Recognition" accepted at IEEE International C

Pedro Neto 21 Nov 17, 2022
Towards Part-Based Understanding of RGB-D Scans

Towards Part-Based Understanding of RGB-D Scans (CVPR 2021) We propose the task of part-based scene understanding of real-world 3D environments: from

26 Nov 23, 2022
Official code for the CVPR 2022 (oral) paper "Extracting Triangular 3D Models, Materials, and Lighting From Images".

nvdiffrec Joint optimization of topology, materials and lighting from multi-view image observations as described in the paper Extracting Triangular 3D

NVIDIA Research Projects 1.4k Jan 01, 2023
The code for our paper Semi-Supervised Learning with Multi-Head Co-Training

Semi-Supervised Learning with Multi-Head Co-Training (PyTorch) Abstract Co-training, extended from self-training, is one of the frameworks for semi-su

cmc 6 Dec 04, 2022
The dataset and source code for our paper: "Did You Ask a Good Question? A Cross-Domain Question IntentionClassification Benchmark for Text-to-SQL"

TriageSQL The dataset and source code for our paper: "Did You Ask a Good Question? A Cross-Domain Question Intention Classification Benchmark for Text

Yusen Zhang 22 Nov 09, 2022
A curated list of awesome projects and resources related fastai

A curated list of awesome projects and resources related fastai

Tanishq Abraham 138 Dec 22, 2022
A python implementation of Deep-Image-Analogy based on pytorch.

Deep-Image-Analogy This project is a python implementation of Deep Image Analogy.https://arxiv.org/abs/1705.01088. Some results Requirements python 3

Peng Lu 171 Dec 14, 2022
BoxInst: High-Performance Instance Segmentation with Box Annotations

Introduction This repository is the code that needs to be submitted for OpenMMLab Algorithm Ecological Challenge, the paper is BoxInst: High-Performan

88 Dec 21, 2022