Do you want to reduce the number of characters in your python codes?
Regarding with
statement, OWith helps you.
Python with
statement is useful.
A little bit long python script like
import json
f = open("sample.json")
try:
dic = json.load(f)
finally:
f.close()
becomes the following short script like
import json
with open("sample.json") as f:
dic = json.load(f)
with with
.
Also, using with
, __enter__
and __exit__
methods of a context manager are called automatically.
For example, you can use your custom context manager
class CustomCM:
def __enter__(self):
print("Start")
def __exit__(self):
print("End")
with with
like the followings.
>>> with CustomCM():
... print("Excecution")
...
start
Execution
end
As above, needless to say, with
is quite helpful for you to write python codes.
However, OWith provides you an alternative tool which enables you to write fewer characters when you use with
to execute one-line suite.
OWith also enables you to use close
or __exit__
required objects like open("sample.json")
in list comprehensions and so on with the confidence that it is safe.
- Python >= 3.7
pip install git+https://github.com/hmasdev/owith.git@master
OWith provides three functions:
owith
: a functional likefunctools.partial
which help you to usewith
;owith_all
: a decorator which help you to create a function in which the arguments will be used inwith
statement;dcwith
: a function to create a decorator which enable you to usewith
outside of a decorated function.
When writing
with some_context_manager as scm:
ret = some_function(scm)
, you can alternatively write
ret = owith(some_function, scm)
with owith
.
When some_function is able to received scm
as a keyword argument kwarg
in the above example, you can also write
ret = owith(some_function, kwarg=scm)
with owith
.
Of course, owith
can receive context managers at once like
ret = owith(some_function, cm1, cm2, cm3=cm3)
which behaves as the same as
with cm1 as cm1_, cm2 as cm2_, cm3 as cm3_:
ret = some_function(cm1_, cm2_, cm3=cm3_)
By the way, if you are concerned when writing
from glob import glob
jsons = [
json.load(open(fname))
for fname in glob("./*.json")
]
, you can also write the following
from glob import glob
jsons = [
owith(json.load, open(fname))
for fname in glob("./*.json")
]
When writing
def func(cm):
with cm as cm_:
return True
, you can alternatively write
@owith_all
def func(cm):
return True
with owith_all
decorator.
When writing
def func():
return True
with cm1, cm2, ..., cmN:
func()
, you can alternatively write
def func():
return True
dcwith(cm1, cm2, ..., cmN)(func)()
or
@dcwith(cm1, cm2, ..., cmN)
def func():
return True
func()
with dcwith
.
Let us see the impact of OWith on your python codes using three example.
Assume that import json
have been already executed in the following examples.
The following python scripts are funcionally equivalent:
with open("sample.json") as f:
dic = json.load(f)
and
ret = owith(json.load, open("sample.json"))
But the number of characters in the former is 52 while that in the latter is 43.
That is, owith
reduce the number of characters by 9.
The following python scripts are functionally equivalent:
def jload(file_obj):
with file_obj as f:
return json.load(f)
and
@owith_all
def jload(file_obj):
return json_load(file_obj)
But the number of characters in the former is 70 while that in the latter is 60.
That is, owith_all
reduce the number of characters by 10.
The following python scripts are functionally equivalent:
def func():
return True
with stopwatch_cm:
func()
and
@dcwith(stopwatch_cm)
def func():
return True
func()
But the number of characters in the former is 54 while that in the latter is 53.
That is, dcwith
reduce the number of characters by 1.
- python >= 3.7
- pipenv
$ git clone https://github.com/hmasdev/owith.git
$ cd owith
$ pipenv install --dev
-
For any bugs, use BUG REPORT to create an issue.
-
For any enhancement, use FEATURE REQUEST to create an issue.
-
For other topics, create an issue with a clear and concise description.
- Fork (https://github.com/hmasdev/owith/fork);
- Create your feature branch (git checkout -b feautre/xxxx);
- Test codes according to Test Subsection;
- Commit your changes (git commit -am 'Add xxxx feature);
- Push to the branch (git push origin feature/xxxx);
- Create new Pull Request
$ pipenv run flake8
$ pipenv run mypy .
$ pipenv run pytest
MIT