- inline the existing contents of _load by indenting within the conditional - just add the new code at the top of the function
Yes, this is what I was referring to; I'd choose one of these options. I'm not so sure about dispatch because it is solely based on type and isn't very flexible; if in the future any change is made to the definition of path-like, or another addition is made to `json.load`/`json.dump`, or whatever, the type-based dispatch option is more likely to need more changes. On Fri, 18 Sep 2020 at 04:22, Wes Turner <wes.turner@gmail.com> wrote:
There's a small amount of overhead to overloading: - 2x conditionals - 1x function call overhead (additional stack frame)
Instead of this approach we could either - inline the existing contents of _load by indenting within the conditional - just add the new code at the top of the function - use multiple dispatch
```python import os import json import pathlib
def test_load(n): print(('n', n, load)) with open('test.json','w') as f: json.dump(True, f) assert load('test.json') assert load(pathlib.Path('test.json')) with open('test.json', 'r') as f: assert load(f)
def _load(file_, **kwargs): # ... rename existing json.load to json._load ... print(('load', file_, kwargs)) return True
def load(file_, *, encoding="UTF-8", **kwargs): if isinstance(file_, str) or hasattr(file_, "__fspath__"): with open(os.fspath(file_), "r", encoding=encoding) as f: return _load(f, **kwargs) else: return _load(file_, **kwargs)
test_load(1)
def load(file_, *, encoding="UTF-8", **kwargs): if isinstance(file_, str) or hasattr(file_, "__fspath__"): with open(os.fspath(file_), "r", encoding=encoding) as f: return _load(f, **kwargs) return _load(file_, **kwargs) # (or inline the existing json.load)
test_load(2)
## singledispatch # https://docs.python.org/3/library/functools.html?highlight=dispatch#functool...
from functools import singledispatch
@singledispatch def load(file_, **kwargs): return _load(file_, **kwargs)
@load.register(str) def load_str(file_: str, *, encoding='UTF-8', **kwargs): with open(file_, "r", encoding=encoding) as f: return _load(f, **kwargs)
@load.register(os.PathLike) def load_pathlike(file_: os.PathLike, *, encoding='UTF-8', **kwargs): with open(os.fspath(file_), "r", encoding=encoding) as f: return _load(f, **kwargs)
test_load(3) ```
On Thu, Sep 17, 2020 at 10:08 PM Inada Naoki <songofacandy@gmail.com> wrote:
On Fri, Sep 18, 2020 at 12:07 AM Paolo Lammens <lammenspaolo@gmail.com> wrote:
Besides, I don't understand what the downside of overloading is, apart
from purism (?).
I am one of who are conservative about overloading. I agree this is purism, but I want to explain behind of this purism.
In statically, and nominal typed language, overloading is simple and clear because only one type is chosen by compiler. On the other hand, compiler or VM can not choose single type in duck-typed (or structural typed) languages.
For example,
* str subtype can implement read/write method. It is both of PathLike and file-like. * File subtype can implement `.__fspath__`. It is both of PathLike and File.
Of course, statically typed languages like Java allow implementing multiple interfaces. But Java programmer must choose one interface explicitly when it is ambiguous. So it is explicit what type is used in overloading.
On the other hand, in case of Python, there are no compiler/VM support for overloading, because Python is duck-typed language.
* `load(f, ...)` uses `f.read()` * `dump(f, ...)` uses `f.write()` * `loadf(path, ..)` and `dumpf(path, ...)` uses `open(path, ...)`
This is so natural design for duck-typed language.
Regards, -- Inada Naoki <songofacandy@gmail.com> _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/ZZOHJI... Code of Conduct: http://python.org/psf/codeofconduct/