{ "info": { "author": "Marcin Biernat", "author_email": "mb@marcinbiernat.pl", "bugtrack_url": null, "classifiers": [ "Development Status :: 2 - Pre-Alpha", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5" ], "description": "Precious\n========\n\n.. image:: https://img.shields.io/pypi/pyversions/precious.svg\n :target: https://pypi.python.org/pypi/precious\n :alt: Latest PyPI version\n\n.. image:: https://travis-ci.org/biern/precious.svg?branch=master\n :target: https://travis-ci.org/biern/precious\n :alt: Latest Travis CI build status\n\nValue objects for Python.\n\n\nExample\n-------\n\n.. code-block:: python\n\n from precious import Value, assign_attributes\n\n\n class Color(Value):\n @assign_attributes\n def __init__(self, red, green, blue, alpha=0): pass\n\n @property\n def grayscale(self):\n return (self.r + self.g + self.b) / 3\n\n\n.. code-block:: python\n\n >>> red = Color(255, 0, 0)\n >>> red\n Color(255, 0, 0, 0)\n >>> red == Color(255, 0, 0)\n True\n >>> Color.__slots__\n ('red', 'green', 'blue', 'alpha')\n >>> hash(red)\n 8736776571231852889\n\n\nInstallation\n------------\n\n.. code-block::\n\n pip install precious\n\n\nUsage\n-----\n\nValue object classes should subclass base ``Value`` class. Every ``Value`` subclass has to define ``attributes``, which is an iterable containing names of all attributes.\nThis may happen by explicitly setting the attribute on the class:\n\n.. code-block:: python\n\n class Point(Value):\n attributes = ('x', 'y')\n\n def __init__(self, x, y):\n self.x = x\n self.y = y\n\n\nBy extracting attribute names directly from ``__init__`` definition using one of provided helper decorators:\n\n.. code-block:: python\n\n from precious import Value, extract_attributes\n\n class Point(Value):\n @extract_attributes\n def __init__(self, x, y):\n self.x = x\n self.y = y\n\n\nBy using a shortcut ``assign_attributes`` to replace a common boilerplate of extracting and assigning all the attributes in ``__init__``:\n\n.. code-block:: python\n\n from precious import Value, assign_attributes\n\n class Point(Value):\n @assign_attributes\n def __init__(self, x, y): pass\n\n\nNote that in the example above attributes are not being assigned in parent's class ``__init__``, thus no ``super()`` call is required.\n\n\nFeatures\n--------\n\n``Value`` implements\n********************\n\n* ``__eq__``\n* ``__repr__``\n* ``__hash__``\n\n\nMemory efficiency\n*****************\n\nSubclassing ``Value`` automaticaly assignes names of all attributes to ``__slots__`` [1]_.\n\nTesting\n-------\n\nJust run ``tox`` in package directory:\n\n.. code-block:: bash\n\n $ tox\n\n\nWhy not simply use ``namedtuple``?\n----------------------------------\n\nNamedtuple definition is equally fine for simple use cases.\n\n.. code-block:: python\n\n Point = namedtuple('Point', ('x', 'y'))\n\n\nHaving to repeat the classname is a minor inconvinience, but the definition is pretty readable and concise. Also, class gets iterable interface and indexing support, which sometimes is what you want. However, things with namedtuple get very ugly when a default value or a method or a property is required. Subclassing is the only way to go. Consider the following example:\n\n.. code-block:: python\n\n class Color(namedtuple('Color_', ('r', 'g', 'b', 'alpha'))):\n __slots__ = ()\n\n def __new__(cls, r, g, b, alpha=0):\n return super().__new__(cls, r, g, b, alpha)\n\n @property\n def grayscale(self):\n return (self.r + self.g + self.b) / 3\n\n # Equivalent to\n\n class Color(Value):\n @assign_attributes\n def __init__(self, red, green, blue, alpha=0): pass\n\n @property\n def grayscale(self):\n return (self.r + self.g + self.b) / 3\n\n\nTo sum up, problems with extending namedtuple include:\n\n* Having to define empty ``__slots__`` [1]_.\n* Overriding ``__new__`` when a default values is required.\n* Repeating attributes names in several places.\n* Unintuitive inheritance by generating parent class on the fly.\n\n\n.. [1] https://docs.python.org/3/reference/datamodel.html#slots", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/biern/precious", "keywords": null, "license": "UNKNOWN", "maintainer": null, "maintainer_email": null, "name": "precious", "package_url": "https://pypi.org/project/precious/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/precious/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/biern/precious" }, "release_url": "https://pypi.org/project/precious/0.1.1/", "requires_dist": null, "requires_python": null, "summary": "Value objects for Python", "version": "0.1.1" }, "last_serial": 2435265, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "9114f70eaa9305ab6ed73d1c5b80d3c1", "sha256": "ee6b66d680d1e671302af9b55b3170680be87bf3d5f4271f29e66ad52e624485" }, "downloads": -1, "filename": "precious-0.1.0.tar.gz", "has_sig": false, "md5_digest": "9114f70eaa9305ab6ed73d1c5b80d3c1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2649, "upload_time": "2016-09-29T18:58:50", "url": "https://files.pythonhosted.org/packages/67/07/bd5d425f0d4abe00e4a9cd37eefadaceada4b16b974e802eb6c7907b8ce0/precious-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "85dbfd981a4c80d00303ff28a577569a", "sha256": "e2bb253292c15bdb45c0e8e1c8db83c94f1c6e51aa5862a469f55fd5b8b60330" }, "downloads": -1, "filename": "precious-0.1.1.tar.gz", "has_sig": false, "md5_digest": "85dbfd981a4c80d00303ff28a577569a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4085, "upload_time": "2016-11-01T14:40:01", "url": "https://files.pythonhosted.org/packages/95/29/a18d12e52cd6aa735b7e974d7d62ab67f70e4df3ae9f9eb09fbad5b72fd5/precious-0.1.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "85dbfd981a4c80d00303ff28a577569a", "sha256": "e2bb253292c15bdb45c0e8e1c8db83c94f1c6e51aa5862a469f55fd5b8b60330" }, "downloads": -1, "filename": "precious-0.1.1.tar.gz", "has_sig": false, "md5_digest": "85dbfd981a4c80d00303ff28a577569a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4085, "upload_time": "2016-11-01T14:40:01", "url": "https://files.pythonhosted.org/packages/95/29/a18d12e52cd6aa735b7e974d7d62ab67f70e4df3ae9f9eb09fbad5b72fd5/precious-0.1.1.tar.gz" } ] }