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
A PaddlePaddle implementation of STGCN with a few modifications in the model architecture in order to forecast traffic jam.

About This repository contains the code of a PaddlePaddle implementation of STGCN based on the paper Spatio-Temporal Graph Convolutional Networks: A D

Tianjian Li 1 Jan 11, 2022
TensorFlow port of PyTorch Image Models (timm) - image models with pretrained weights.

TensorFlow-Image-Models Introduction Usage Models Profiling License Introduction TensorfFlow-Image-Models (tfimm) is a collection of image models with

Martins Bruveris 227 Dec 20, 2022
This repository contains a PyTorch implementation of "AD-NeRF: Audio Driven Neural Radiance Fields for Talking Head Synthesis".

AD-NeRF: Audio Driven Neural Radiance Fields for Talking Head Synthesis | Project Page | Paper | PyTorch implementation for the paper "AD-NeRF: Audio

551 Dec 29, 2022
Implementation for Paper "Inverting Generative Adversarial Renderer for Face Reconstruction"

StyleGAR TODO: add arxiv link Implementation of Inverting Generative Adversarial Renderer for Face Reconstruction TODO: for test Currently, some model

155 Oct 27, 2022
Code for "R-GCN: The R Could Stand for Random"

RR-GCN: Random Relational Graph Convolutional Networks PyTorch Geometric code for the paper "R-GCN: The R Could Stand for Random" RR-GCN is an extensi

PreDiCT.IDLab 31 Sep 07, 2022
simple demo codes for Learning to Teach with Dynamic Loss Functions

Learning to Teach with Dynamic Loss Functions This repo contains the simple demo for the NeurIPS-18 paper: Learning to Teach with Dynamic Loss Functio

Lijun Wu 15 Dec 30, 2021
Official code repository for the EMNLP 2021 paper

Integrating Visuospatial, Linguistic and Commonsense Structure into Story Visualization PyTorch code for the EMNLP 2021 paper "Integrating Visuospatia

Adyasha Maharana 23 Dec 19, 2022
git《Tangent Space Backpropogation for 3D Transformation Groups》(CVPR 2021) GitHub:1]

LieTorch: Tangent Space Backpropagation Introduction The LieTorch library generalizes PyTorch to 3D transformation groups. Just as torch.Tensor is a m

Princeton Vision & Learning Lab 482 Jan 06, 2023
TaCL: Improving BERT Pre-training with Token-aware Contrastive Learning

TaCL: Improving BERT Pre-training with Token-aware Contrastive Learning Authors: Yixuan Su, Fangyu Liu, Zaiqiao Meng, Lei Shu, Ehsan Shareghi, and Nig

Yixuan Su 79 Nov 04, 2022
Concept drift monitoring for HA model servers.

{Fast, Correct, Simple} - pick three Easily compare training and production ML data & model distributions Goals Boxkite is an instrumentation library

98 Dec 15, 2022
Code for Emergent Translation in Multi-Agent Communication

Emergent Translation in Multi-Agent Communication PyTorch implementation of the models described in the paper Emergent Translation in Multi-Agent Comm

Facebook Research 75 Jul 15, 2022
This is the official code for the paper "Ad2Attack: Adaptive Adversarial Attack for Real-Time UAV Tracking".

Ad^2Attack:Adaptive Adversarial Attack on Real-Time UAV Tracking Demo video 📹 Our video on bilibili demonstrates the test results of Ad^2Attack on se

Intelligent Vision for Robotics in Complex Environment 10 Nov 07, 2022
Gesture recognition on Event Data

Event based Gesture Recognition Gesture recognition on Event Data usually involv

2 Feb 14, 2022
yolov5 deepsort 行人 车辆 跟踪 检测 计数

yolov5 deepsort 行人 车辆 跟踪 检测 计数 实现了 出/入 分别计数。 默认是 南/北 方向检测,若要检测不同位置和方向,可在 main.py 文件第13行和21行,修改2个polygon的点。 默认检测类别:行人、自行车、小汽车、摩托车、公交车、卡车。 检测类别可在 detect

554 Dec 30, 2022
Code for Multiple Instance Active Learning for Object Detection, CVPR 2021

MI-AOD Language: 简体中文 | English Introduction This is the code for Multiple Instance Active Learning for Object Detection (The PDF is not available tem

Tianning Yuan 269 Dec 21, 2022
Simulation of Self Driving Car

In this repository, the code to use Udacity's self driving car simulator as a testbed for training an autonomous car are provided.

Shyam Das Shrestha 1 Nov 21, 2021
Volumetric parameterization of the placenta to a flattened template

placenta-flattening A MATLAB algorithm for volumetric mesh parameterization. Developed for mapping a placenta segmentation derived from an MRI image t

Mazdak Abulnaga 12 Mar 14, 2022
Cobalt Strike teamserver detection.

Cobalt-Strike-det Cobalt Strike teamserver detection. usage: cobaltstrike_verify.py [-l TARGETS] [-t THREADS] optional arguments: -h, --help show this

TimWhite 17 Sep 27, 2022
This is a Image aid classification software based on python TK library development

This is a Image aid classification software based on python TK library development.

EasonChan 1 Jan 17, 2022
An AFL implementation with UnTracer (our coverage-guided tracer)

UnTracer-AFL This repository contains an implementation of our prototype coverage-guided tracing framework UnTracer in the popular coverage-guided fuz

113 Dec 17, 2022