oba


Nameoba JSON
Version 0.0.9 PyPI version JSON
download
home_pagehttps://github.com/Jyonn/Oba
Summarymake iter object easy to access (item to attr)
upload_time2024-12-04 10:36:17
maintainerNone
docs_urlNone
authorJyonn Liu
requires_pythonNone
licenseMIT Licence
keywords dict object
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Oba: Converting a Python Iterable Object to an Attribute Class

![PyPI](https://img.shields.io/pypi/v/oba.svg)
![GitHub](https://img.shields.io/github/license/Jyonn/Oba.svg)

## Introduction

Converting iterable objects (such as dictionaries, tuples, lists, sets, and subclasses) to access values using class attributes instead of square brackets `[]`. Supports recursive operations and supports both getting and setting values.

## Installation

`pip install oba`

## Usage

```python
from oba import Obj

# Convert a dictionary to an attribute class
d = dict(a=[1, 2, 3], b=[4, dict(x=1)], c=dict(l='hello'))
o = Obj(d)

# Get values
print(o.a[2])  # => 3
print(o.c.l)  # => hello

# Set values
o.b[1].x = 4
print(Obj.raw(o.b[1]))  # => {'x': 4}

points = [dict(x=1, y=2), dict(x=-1, y=0), dict(x=0, y=1)]
o = Obj(points)

o[0].x += 1
print(Obj.raw(o[0]))  # => {'x': 2, 'y': 2}

o['c.l'] = 'world'
print(o.c.l)  # => world
```

## Comparison

### namedtuple (built-in module)

```python
from collections import namedtuple

o = namedtuple('Struct', d.keys())(*d.values())

print(o)  # => Struct(a=[1, 2, 3], b=[4, {'x': 1}], c={'l': 'hello'})
print(o.a)  # => [1, 2, 3]

o.x = 2  # => AttributeError
```

### bunch (package)

```python
from bunch import Bunch

o = Bunch(d)

print(o.a)  # => [1, 2, 3]
print(o.b['x'])  # => 1
print(o.b.x)  # => KeyError

o.x = 2  # OK, editable

o = Bunch(points)  # => AttributeError
```

### json (built-in module)

```python
import json

class Obj(object):
    def __init__(self, d):
        self.__dict__.update(d)

o = json.loads(json.dumps(d), object_hook=Obj)

print(o.a[2])  # => 3
print(o.c.l)  # => hello

o.x = 2  # OK, editable

o = Obj(points)

o[0].x += 1
print(o[0].x)  # => 2
```

### mock (package) 

```python
from mock import Mock

o = Mock(**d)

print(o.a)  # => [1, 2, 3]
print(o.b['x'])  # => 1
print(o.b.x)  # => KeyError

o.x = 2  # OK

o = Mock(*points)  # => TypeError
```

### Summary

| Feature       | namedtuple  | bunch (2011)              | json | mock (2020) | Oba (2022) |
|---------------|-------------|---------------------------|------|-------------|------------|
| built-in      | ✓           | ✗ 11K                     | ✓    | ✗ 28K       | ✗ 3K       |
| recursive     | ✗           | ✗                         | ✓    | ✗           | ✓          |
| revert to raw | ✗           | ✓ (with extra operations) | ✗    | ✗           | ✓          |
| editable      | ✗           | ✓                         | ✓    | ✓           | ✓          |
| iterable      | ✓ (no keys) | ✓                         | ✗    | ✗           | ✓          |
| support dict  | ✓           | ✓                         | ✓    | ✓           | ✓          |
| support list  | ✓           | ✗                         | ✓    | ✗           | ✓          |
| support tuple | ✗           | ✗                         | ✓    | ✗           | ✓          |
| _tolerable_   | ✗           | ✗                         | ✗    | ✗           | ✓          |

## Features

Additionally, `Oba` also has a unique tolerance for unknown attributes. In cases where some attributes do not exist, for example:

```python
d = dict(a=1)
print(d['b'])  # KeyError
```

Other libraries will immediately raise an error. However, in some scenarios (such as reading configuration files), the absence of sub-attributes is a common problem, and we hope to be able to tolerate and monitor the existence of such errors.

```python
from oba import Obj

d = dict(a=1)
o = Obj(d)

print('x' in o)  # => False
if not o.x.y.z:  # OK
    print('not exist')  # => not exist
print(o.x.y.z)  # => ValueError: NoneObj (x.y.z)  # locating the non-existent attribute chain
```

Its internal implementation is that when an attribute does not exist, the object automatically switches to the `NoneObj` class and records the attribute chain.

## License

MIT



            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/Jyonn/Oba",
    "name": "oba",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "dict, object",
    "author": "Jyonn Liu",
    "author_email": "i@6-79.cn",
    "download_url": "https://files.pythonhosted.org/packages/65/f0/494316fedf6875790a9d3ca3c3396356adbbd8117775ad6ced14e8d5ed9f/oba-0.0.9.tar.gz",
    "platform": "any",
    "description": "# Oba: Converting a Python Iterable Object to an Attribute Class\n\n![PyPI](https://img.shields.io/pypi/v/oba.svg)\n![GitHub](https://img.shields.io/github/license/Jyonn/Oba.svg)\n\n## Introduction\n\nConverting iterable objects (such as dictionaries, tuples, lists, sets, and subclasses) to access values using class attributes instead of square brackets `[]`. Supports recursive operations and supports both getting and setting values.\n\n## Installation\n\n`pip install oba`\n\n## Usage\n\n```python\nfrom oba import Obj\n\n# Convert a dictionary to an attribute class\nd = dict(a=[1, 2, 3], b=[4, dict(x=1)], c=dict(l='hello'))\no = Obj(d)\n\n# Get values\nprint(o.a[2])  # => 3\nprint(o.c.l)  # => hello\n\n# Set values\no.b[1].x = 4\nprint(Obj.raw(o.b[1]))  # => {'x': 4}\n\npoints = [dict(x=1, y=2), dict(x=-1, y=0), dict(x=0, y=1)]\no = Obj(points)\n\no[0].x += 1\nprint(Obj.raw(o[0]))  # => {'x': 2, 'y': 2}\n\no['c.l'] = 'world'\nprint(o.c.l)  # => world\n```\n\n## Comparison\n\n### namedtuple (built-in module)\n\n```python\nfrom collections import namedtuple\n\no = namedtuple('Struct', d.keys())(*d.values())\n\nprint(o)  # => Struct(a=[1, 2, 3], b=[4, {'x': 1}], c={'l': 'hello'})\nprint(o.a)  # => [1, 2, 3]\n\no.x = 2  # => AttributeError\n```\n\n### bunch (package)\n\n```python\nfrom bunch import Bunch\n\no = Bunch(d)\n\nprint(o.a)  # => [1, 2, 3]\nprint(o.b['x'])  # => 1\nprint(o.b.x)  # => KeyError\n\no.x = 2  # OK, editable\n\no = Bunch(points)  # => AttributeError\n```\n\n### json (built-in module)\n\n```python\nimport json\n\nclass Obj(object):\n    def __init__(self, d):\n        self.__dict__.update(d)\n\no = json.loads(json.dumps(d), object_hook=Obj)\n\nprint(o.a[2])  # => 3\nprint(o.c.l)  # => hello\n\no.x = 2  # OK, editable\n\no = Obj(points)\n\no[0].x += 1\nprint(o[0].x)  # => 2\n```\n\n### mock (package) \n\n```python\nfrom mock import Mock\n\no = Mock(**d)\n\nprint(o.a)  # => [1, 2, 3]\nprint(o.b['x'])  # => 1\nprint(o.b.x)  # => KeyError\n\no.x = 2  # OK\n\no = Mock(*points)  # => TypeError\n```\n\n### Summary\n\n| Feature       | namedtuple  | bunch (2011)              | json | mock (2020) | Oba (2022) |\n|---------------|-------------|---------------------------|------|-------------|------------|\n| built-in      | \u2713           | \u2717 11K                     | \u2713    | \u2717 28K       | \u2717 3K       |\n| recursive     | \u2717           | \u2717                         | \u2713    | \u2717           | \u2713          |\n| revert to raw | \u2717           | \u2713 (with extra operations) | \u2717    | \u2717           | \u2713          |\n| editable      | \u2717           | \u2713                         | \u2713    | \u2713           | \u2713          |\n| iterable      | \u2713 (no keys) | \u2713                         | \u2717    | \u2717           | \u2713          |\n| support dict  | \u2713           | \u2713                         | \u2713    | \u2713           | \u2713          |\n| support list  | \u2713           | \u2717                         | \u2713    | \u2717           | \u2713          |\n| support tuple | \u2717           | \u2717                         | \u2713    | \u2717           | \u2713          |\n| _tolerable_   | \u2717           | \u2717                         | \u2717    | \u2717           | \u2713          |\n\n## Features\n\nAdditionally, `Oba` also has a unique tolerance for unknown attributes. In cases where some attributes do not exist, for example:\n\n```python\nd = dict(a=1)\nprint(d['b'])  # KeyError\n```\n\nOther libraries will immediately raise an error. However, in some scenarios (such as reading configuration files), the absence of sub-attributes is a common problem, and we hope to be able to tolerate and monitor the existence of such errors.\n\n```python\nfrom oba import Obj\n\nd = dict(a=1)\no = Obj(d)\n\nprint('x' in o)  # => False\nif not o.x.y.z:  # OK\n    print('not exist')  # => not exist\nprint(o.x.y.z)  # => ValueError: NoneObj (x.y.z)  # locating the non-existent attribute chain\n```\n\nIts internal implementation is that when an attribute does not exist, the object automatically switches to the `NoneObj` class and records the attribute chain.\n\n## License\n\nMIT\n\n\n",
    "bugtrack_url": null,
    "license": "MIT Licence",
    "summary": "make iter object easy to access (item to attr)",
    "version": "0.0.9",
    "project_urls": {
        "Homepage": "https://github.com/Jyonn/Oba"
    },
    "split_keywords": [
        "dict",
        " object"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "65f0494316fedf6875790a9d3ca3c3396356adbbd8117775ad6ced14e8d5ed9f",
                "md5": "ce052aec728757d2778984356a376156",
                "sha256": "bdc5320f3965bf4cf04c042dbde75824218911fdf3840c6c334d62eaf2644c7e"
            },
            "downloads": -1,
            "filename": "oba-0.0.9.tar.gz",
            "has_sig": false,
            "md5_digest": "ce052aec728757d2778984356a376156",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 4177,
            "upload_time": "2024-12-04T10:36:17",
            "upload_time_iso_8601": "2024-12-04T10:36:17.279699Z",
            "url": "https://files.pythonhosted.org/packages/65/f0/494316fedf6875790a9d3ca3c3396356adbbd8117775ad6ced14e8d5ed9f/oba-0.0.9.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-12-04 10:36:17",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Jyonn",
    "github_project": "Oba",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "oba"
}
        
Elapsed time: 3.27251s