--verbose 또는 -v 옵션을 스크립트에 구현하는 방법은 무엇입니까?
나는 알고 --verbose
또는 -v
여러 툴을 나는 내 자신의 스크립트와 도구의 일부에이를 구현하고 싶습니다.
나는 배치를 생각했다 :
if verbose:
print ...
내 소스 코드를 통해 사용자가 -v
옵션을 전달 하면 변수 verbose
가로 설정되고 True
텍스트가 인쇄됩니다.
이것이 올바른 접근 방식입니까 아니면 더 일반적인 방법이 있습니까?
추가 : 인수 구문 분석을 구현하는 방법을 요구하지 않습니다. 나는 그것이 어떻게 행해지는지 압니다. 나는 verbose 옵션에만 특별히 관심이 있습니다.
내 제안은 기능을 사용하는 것입니다. 하지만 if
당신이하고 싶은 유혹을 함수에 넣는 대신 다음과 같이하세요 :
if verbose:
def verboseprint(*args):
# Print each argument separately so caller doesn't need to
# stuff everything to be printed into a single string
for arg in args:
print arg,
print
else:
verboseprint = lambda *a: None # do-nothing function
(예, if
명령문 에서 함수를 정의 할 수 있으며 조건이 참인 경우에만 정의됩니다!)
print
이미 함수가 있는 Python 3 을 사용하는 경우 ( print
또는를 사용하여 2.x에서 함수 로 사용하려는 경우 from __future__ import print_function
) 더 간단합니다.
verboseprint = print if verbose else lambda *a, **k: None
이렇게하면 verbose
플래그 를 지속적으로 테스트하는 대신 verbose 모드가 꺼져있는 경우 (람다 사용) 함수가 아무것도하지 않는 것으로 정의됩니다 .
사용자가 프로그램을 실행 하는 동안 상세 모드를 변경할 수 있다면 이것은 잘못된 접근 방식입니다 ( if
함수에서 필요 ).하지만 명령 줄 플래그로 설정하기 때문에 한 번 결정하십시오.
그런 다음 verboseprint("look at all my verbosity!", object(), 3)
"verbose"메시지를 인쇄 할 때마다 예를 사용 합니다.
logging
모듈 사용 :
import logging as log
…
args = p.parse_args()
if args.verbose:
log.basicConfig(format="%(levelname)s: %(message)s", level=log.DEBUG)
log.info("Verbose output.")
else:
log.basicConfig(format="%(levelname)s: %(message)s")
log.info("This should be verbose.")
log.warning("This is a warning.")
log.error("This is an error.")
이 모든 것이 자동으로 다음으로 이동합니다 stderr
.
% python myprogram.py
WARNING: This is a warning.
ERROR: This is an error.
% python myprogram.py -v
INFO: Verbose output.
INFO: This should be verbose.
WARNING: This is a warning.
ERROR: This is an error.
자세한 내용은 Python 문서 및 자습서를 참조 하세요 .
@kindall의 답변을 작성하고 단순화하면 다음과 같이 일반적으로 사용합니다.
v_print = None
def main()
parser = argparse.ArgumentParser()
parser.add_argument('-v', '--verbosity', action="count",
help="increase output verbosity (e.g., -vv is more than -v)")
args = parser.parse_args()
if args.verbosity:
def _v_print(*verb_args):
if verb_args[0] > (3 - args.verbosity):
print verb_args[1]
else:
_v_print = lambda *a: None # do-nothing function
global v_print
v_print = _v_print
if __name__ == '__main__':
main()
그러면 스크립트 전체에서 다음 사용법이 제공됩니다.
v_print(1, "INFO message")
v_print(2, "WARN message")
v_print(3, "ERROR message")
그리고 스크립트는 다음과 같이 호출 할 수 있습니다.
% python verbose-tester.py -v
ERROR message
% python verbose=tester.py -vv
WARN message
ERROR message
% python verbose-tester.py -vvv
INFO message
WARN message
ERROR message
몇 가지 참고 사항 :
- 첫 번째 인수는 오류 수준이고 두 번째 인수는 메시지입니다.
3
로깅의 상한을 설정 하는 매직 넘버가 있지만 단순성을위한 타협으로 받아들입니다. v_print
프로그램 전체에서 일하고 싶다면 글로벌과 함께 쓰레기를 처리해야합니다. 재미는 없지만 더 나은 방법을 찾기 위해 누군가에게 도전합니다.
What I do in my scripts is check at runtime if the 'verbose' option is set, and then set my logging level to debug. If it's not set, I set it to info. This way you don't have 'if verbose' checks all over your code.
It might be cleaner if you have a function, say called vprint
, that checks the verbose flag for you. Then you just call your own vprint
function any place you want optional verbosity.
I stole the logging code from virtualenv for a project of mine. Look in main()
of virtualenv.py
to see how it's initialized. The code is sprinkled with logger.notify()
, logger.info()
, logger.warn()
, and the like. Which methods actually emit output is determined by whether virtualenv was invoked with -v
, -vv
, -vvv
, or -q
.
@kindall's solution does not work with my Python version 3.5. @styles correctly states in his comment that the reason is the additional optional keywords argument. Hence my slightly refined version for Python 3 looks like this:
if VERBOSE:
def verboseprint(*args, **kwargs):
print(*args, **kwargs)
else:
verboseprint = lambda *a, **k: None # do-nothing function
There could be a global variable, likely set with argparse
from sys.argv
, that stands for whether the program should be verbose or not. Then a decorator could be written such that if verbosity was on, then the standard input would be diverted into the null device as long as the function were to run:
import os
from contextlib import redirect_stdout
verbose = False
def louder(f):
def loud_f(*args, **kwargs):
if not verbose:
with open(os.devnull, 'w') as void:
with redirect_stdout(void):
return f(*args, **kwargs)
return f(*args, **kwargs)
return loud_f
@louder
def foo(s):
print(s*3)
foo("bar")
This answer is inspired by this code; actually, I was going to just use it as a module in my program, but I got errors I couldn't understand, so I adapted a portion of it.
The downside of this solution is that verbosity is binary, unlike with logging
, which allows for finer-tuning of how verbose the program can be. Also, all print
calls are diverted, which might be unwanted for.
What I need is a function which prints an object (obj), but only if global variable verbose is true, else it does nothing.
I want to be able to change the global parameter "verbose" at any time. Simplicity and readability to me are of paramount importance. So I would proceed as the following lines indicate:
ak@HP2000:~$ python3
Python 3.4.3 (default, Oct 14 2015, 20:28:29)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> verbose = True
>>> def vprint(obj):
... if verbose:
... print(obj)
... return
...
>>> vprint('Norm and I')
Norm and I
>>> verbose = False
>>> vprint('I and Norm')
>>>
Global variable "verbose" can be set from the parameter list, too.
참고URL : https://stackoverflow.com/questions/5980042/how-to-implement-the-verbose-or-v-option-into-a-script
'Programing' 카테고리의 다른 글
Eclipse에서 다른 중단 점 아이콘은 무엇을 의미합니까? (0) | 2020.10.14 |
---|---|
JavaScript를 사용하여 레이블 텍스트 변경 (0) | 2020.10.14 |
Rails — STI없이 타입 컬럼을 사용 하시겠습니까? (0) | 2020.10.14 |
JavaFX 2 및 국제화 (0) | 2020.10.14 |
문자열 날짜를 긴 밀리 초로 변환하는 방법 (0) | 2020.10.14 |