# anymethod
> @anymethod = instance method + @classmethod
[](https://github.com/makukha/anymethod/blob/main/LICENSE)
[](https://pypi.python.org/pypi/anymethod)
[](https://pypi.org/project/anymethod)
[](https://github.com/makukha/anymethod)
[](https://github.com/makukha/anymethod)
[](https://github.com/makukha/multipython)
[](https://github.com/makukha/docsub)
For the cases when class and its instances can be used interchangeably, code duplication can be avoided if the same member function works both as `@classmethod` and instance method.
This can be easily achieved with Python [descriptors](https://docs.python.org/3/howto/descriptor.html).
## Installation
```shell
$ pip install anymethod
```
## Example A
<!-- docsub: begin -->
<!-- docsub: include tests/mypy/test_exampleA.txt -->
<!-- docsub: lines after 1 upto -1 -->
```dectest
>>> from anymethod import anymethod
>>> class FooBar:
... @anymethod
... def whoami[O](owner: O) -> O:
... return owner
>>> FooBar.whoami()
<class '__main__.FooBar'>
>>> FooBar().whoami()
<__main__.FooBar object at 0x...>
```
<!-- docsub: end -->
## Example B
<!-- docsub: begin -->
<!-- docsub: include tests/mypy/exampleB.py -->
<!-- docsub: lines after 1 upto -1 -->
```python
from typing import Any, ClassVar
from anymethod import anymethod
class FooBar:
_cls: ClassVar[list[Any]] = []
_obj: list[Any]
def __init__(self) -> None:
self._obj = []
@anymethod
def add_value(owner, v: Any) -> None:
if isinstance(owner, type):
owner._cls.append(v)
else:
owner._obj.append(v)
```
<!-- docsub: end -->
## More info
Check the [Project changelog](https://github.com/makukha/anymethod/tree/main/CHANGELOG.md)
Raw data
{
"_id": null,
"home_page": null,
"name": "anymethod",
"maintainer": null,
"docs_url": null,
"requires_python": "!=3.0,!=3.1,!=3.2,!=3.3,!=3.4,>=2.7",
"maintainer_email": null,
"keywords": "classmethod, descriptor, instance-method, polymorphism",
"author": null,
"author_email": "Michael Makukha <m.makukha@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/46/a2/5bb9378e6899badbc6af275c012b2723d283ae5315fe7b360c5b159c81ce/anymethod-0.1.2.tar.gz",
"platform": null,
"description": "# anymethod\n> @anymethod = instance method + @classmethod\n\n[](https://github.com/makukha/anymethod/blob/main/LICENSE)\n[](https://pypi.python.org/pypi/anymethod)\n[](https://pypi.org/project/anymethod)\n[](https://github.com/makukha/anymethod)\n[](https://github.com/makukha/anymethod)\n[](https://github.com/makukha/multipython)\n[](https://github.com/makukha/docsub)\n\nFor the cases when class and its instances can be used interchangeably, code duplication can be avoided if the same member function works both as `@classmethod` and instance method.\n\nThis can be easily achieved with Python [descriptors](https://docs.python.org/3/howto/descriptor.html).\n\n\n## Installation\n\n```shell\n$ pip install anymethod\n```\n\n\n## Example A\n\n<!-- docsub: begin -->\n<!-- docsub: include tests/mypy/test_exampleA.txt -->\n<!-- docsub: lines after 1 upto -1 -->\n```dectest\n>>> from anymethod import anymethod\n\n>>> class FooBar:\n... @anymethod\n... def whoami[O](owner: O) -> O:\n... return owner\n\n>>> FooBar.whoami()\n<class '__main__.FooBar'>\n\n>>> FooBar().whoami()\n<__main__.FooBar object at 0x...>\n```\n<!-- docsub: end -->\n\n\n## Example B\n\n<!-- docsub: begin -->\n<!-- docsub: include tests/mypy/exampleB.py -->\n<!-- docsub: lines after 1 upto -1 -->\n```python\nfrom typing import Any, ClassVar\nfrom anymethod import anymethod\n\n\nclass FooBar:\n _cls: ClassVar[list[Any]] = []\n _obj: list[Any]\n\n def __init__(self) -> None:\n self._obj = []\n\n @anymethod\n def add_value(owner, v: Any) -> None:\n if isinstance(owner, type):\n owner._cls.append(v)\n else:\n owner._obj.append(v)\n```\n<!-- docsub: end -->\n\n\n## More info\n\nCheck the [Project changelog](https://github.com/makukha/anymethod/tree/main/CHANGELOG.md)\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "@anymethod = instance method and @classmethod",
"version": "0.1.2",
"project_urls": {
"Changelog": "https://github.com/makukha/anymethod/blob/main/CHANGELOG.md",
"Homepage": "https://github.com/makukha/anymethod",
"Issues": "https://github.com/makukha/anymethod/issues",
"Repository": "https://github.com/makukha/anymethod"
},
"split_keywords": [
"classmethod",
" descriptor",
" instance-method",
" polymorphism"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "3edccf3a4d8f0955bbeb72c109e0bf3cb16147a7753918f4aa57186c6a3d19ab",
"md5": "0a3bc7799d389fce850ffbaaf87d2049",
"sha256": "ebdf2904ea569be1317f887f2342dc888baba1f45e2f6e9cc5bdc296880ab91d"
},
"downloads": -1,
"filename": "anymethod-0.1.2-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "0a3bc7799d389fce850ffbaaf87d2049",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": "!=3.0,!=3.1,!=3.2,!=3.3,!=3.4,>=2.7",
"size": 3996,
"upload_time": "2025-02-01T08:27:29",
"upload_time_iso_8601": "2025-02-01T08:27:29.053363Z",
"url": "https://files.pythonhosted.org/packages/3e/dc/cf3a4d8f0955bbeb72c109e0bf3cb16147a7753918f4aa57186c6a3d19ab/anymethod-0.1.2-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "46a25bb9378e6899badbc6af275c012b2723d283ae5315fe7b360c5b159c81ce",
"md5": "6c76e1b4ec0771877ec3ebe8da67c054",
"sha256": "32b663dc654e5934cf2a9d4bde6cbf85196a9678b776b630a344798d5ecb4e00"
},
"downloads": -1,
"filename": "anymethod-0.1.2.tar.gz",
"has_sig": false,
"md5_digest": "6c76e1b4ec0771877ec3ebe8da67c054",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "!=3.0,!=3.1,!=3.2,!=3.3,!=3.4,>=2.7",
"size": 58761,
"upload_time": "2025-02-01T08:27:31",
"upload_time_iso_8601": "2025-02-01T08:27:31.616101Z",
"url": "https://files.pythonhosted.org/packages/46/a2/5bb9378e6899badbc6af275c012b2723d283ae5315fe7b360c5b159c81ce/anymethod-0.1.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-02-01 08:27:31",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "makukha",
"github_project": "anymethod",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"tox": true,
"lcname": "anymethod"
}