স্ক্রিপ্টে --verbose বা -v বিকল্পটি কীভাবে প্রয়োগ করবেন?


95

আমি --verboseবা -vবেশ কয়েকটি সরঞ্জামগুলি জানি এবং আমি এটি আমার নিজস্ব স্ক্রিপ্ট এবং সরঞ্জামগুলির মধ্যে প্রয়োগ করতে চাই।

আমি রাখার কথা ভেবেছিলাম:

if verbose:
    print ...

আমার উত্স কোডের মাধ্যমে, যাতে কোনও ব্যবহারকারী -vবিকল্পটি পাস করে , ভেরিয়েবলটি verboseসেট করা হবে Trueএবং পাঠ্য মুদ্রিত হবে।

এটি কি সঠিক পন্থা বা আরও সাধারণ উপায় আছে?

সংযোজন: আমি যুক্তিগুলির বিশ্লেষণ কার্যকর করার উপায় চাইছি না। আমি জানি যে এটি কীভাবে করা হয়। আমি কেবল বিশেষভাবে ভার্বোজ বিকল্পটিতে আগ্রহী।


9
লগিং মডিউলটি কেন ব্যবহার করবেন না এবং ডিফল্টরূপে লগ স্তর INFO সেট করবেন না এবং --verbose পাস করার পরে DEBUG করবেন? ইতিমধ্যে ভাষায় উপলভ্য যে কোনও কিছুর পুনর্বিবেচনা না করাই সেরা ...
টিম

4
@ টিম, আমি সম্মত, তবে লগিং মডিউলটি বেশ বেদনাদায়ক।
mlissner

উত্তর:


109

আমার পরামর্শটি একটি ফাংশন ব্যবহার করা। তবে 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বিবৃতিতে কোনও ফাংশন সংজ্ঞায়িত করতে পারেন , এবং শর্তটি সত্য হলে এটি কেবল সংজ্ঞায়িত হবে!)

যদি আপনি পাইথন 3 ব্যবহার করেন printতবে ইতিমধ্যে যেখানে কোনও ফাংশন (বা আপনি printযদি 2.x ব্যবহার করে কোনও ফাংশন হিসাবে ব্যবহার করতে ইচ্ছুক হন from __future__ import print_function) এটি আরও সহজ:

verboseprint = print if verbose else lambda *a, **k: None

এভাবে ক্রমাগত verboseপতাকা পরীক্ষার পরিবর্তে ভার্বোস মোড বন্ধ থাকলে (ল্যাম্বডা ব্যবহার করে) ফাংশনটি ডু-কিছুই হিসাবে সংজ্ঞায়িত করা হয় ।

যদি ব্যবহারকারী আপনার প্রোগ্রামটি চলাকালীন ভার্বোসিটি মোড পরিবর্তন করতে পারে, তবে এটি ভুল পদ্ধতির হবে (আপনার ifফাংশনটি দরকার হবে) তবে যেহেতু আপনি এটি একটি কমান্ড-লাইন পতাকা দিয়ে সেট করছেন, আপনার কেবল দরকার একবার সিদ্ধান্ত নিন।

তারপরে আপনি উদাহরণস্বরূপ ব্যবহার করুন verboseprint("look at all my verbosity!", object(), 3)যখনই আপনি কোনও "ভারবোজ" বার্তা মুদ্রণ করতে চান।


4
আরও ভাল, এটি printফাংশন হিসাবে করুন : অনেক যুক্তি গ্রহণ করুন। এটি print(*args)3.x এবং for arg in args: print arg,2.x হিসাবে প্রয়োগ করা যেতে পারে প্রধান সুবিধাটি হ'ল এটি কোনও বার্তায় স্ট্রিং এবং অন্যান্য ধরণের জিনিসগুলিকে সুস্পষ্ট strকল / বিন্যাস এবং কনটেন্টেশন ছাড়াই মেশানোর অনুমতি দেয় ।

print arg,লাইনের শেষে কমা ব্যবহার করা হয় ?
সমক

এটি সহজেই নিজের জন্য পরীক্ষামূলকভাবে বা ডকুমেন্টেশন পরীক্ষা করে নির্ধারিত হয় তবে এটি সাধারণত মুদ্রিত হওয়া লাইন ব্রেকটিকে দমন করে।
পাঠান

4
পাইথন 3 মুদ্রণ ফাংশনটি def verboseprint(*args, **kwargs): print(*args, **kwargs)
optionচ্ছিক

63

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.

আরও তথ্যের জন্য পাইথন ডক্স এবং টিউটোরিয়ালগুলি দেখুন


8
এখানে পাইথন ডক্স অনুসারে, প্রোগ্রামটির সাধারণ সম্পাদনায় আপনার কেবলমাত্র আউটপুট মুদ্রণ করতে হবে এমন ক্ষেত্রে লগিং ব্যবহার করা উচিত নয়। দেখে মনে হচ্ছে ওপি এটিই চায়।
SANDeveloper

4
এটি মূল সমস্যাটির জন্য দুর্দান্ত মনে হলেও অনেক * নিক্স কমান্ডগুলি একাধিক স্তরের ভার্বোসিটি (-v -v -v, ইত্যাদি) সমর্থন করে যা এইভাবে অগোছালো হতে পারে।
টেক্সটগীক

12

@ কিন্ডাল এর উত্তর তৈরি এবং সরলকরণ, আমি সাধারণত যা ব্যবহার করি তা এখানে:

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

একটি দম্পতি নোট:

  1. আপনার প্রথম যুক্তিটি হ'ল আপনার ত্রুটি স্তর এবং দ্বিতীয়টি আপনার বার্তা। এটির ম্যাজিক সংখ্যা রয়েছে 3যা আপনার লগিংয়ের জন্য উপরের সীমাটি নির্ধারণ করে, তবে আমি স্বীকার করি যে এটি সরলতার জন্য একটি আপস হিসাবে।
  2. আপনি যদি আপনার v_printপুরো প্রোগ্রাম জুড়ে কাজ করতে চান তবে আপনাকে গ্লোবালটির সাথে জাঙ্কটি করতে হবে। এটি কোনও মজাদার নয়, তবে আমি কাউকে আরও ভাল উপায় খুঁজতে চ্যালেঞ্জ জানাই।

4
আপনি INFO এবং সতর্কতার জন্য লগিং মডিউলটি কেন ব্যবহার করবেন না? এটি -vব্যবহৃত হলে এটি আমদানি করে । আপনার বর্তমান সমাধানে স্টাডারের পরিবর্তে সমস্ত কিছু স্ট্যাডআউটে ফেলে দেওয়া হয়। এবং: আপনি সাধারণত প্রতিটি ত্রুটি ব্যবহারকারীকে রিলে করতে চান, তাই না?
প্রোফ্যাপাটস

4
হ্যাঁ, এটা মোটামুটি বিষয়। লগিংয়ের কিছু জ্ঞানীয় ওভারহেড রয়েছে যা আমি এড়াতে চাইছিলাম, তবে এটি সম্ভবত "সঠিক" জিনিস। এটি কেবল অতীতে আমাকে বিরক্ত করেছে ...
mlissner

9

আমি আমার স্ক্রিপ্টগুলিতে যা করি তা রানটাইমে চেক করা হয় যদি 'ভার্বোজ' বিকল্পটি সেট করা থাকে এবং তারপরে আমার লগিং স্তরটি ডিবাগের জন্য সেট করে। যদি এটি সেট না করা থাকে তবে আমি তা তথ্যতে সেট করি। এইভাবে আপনার সমস্ত কোডটিতে 'যদি ভার্বোস' চেক থাকে না।


2

এটি যদি আপনার কোনও ক্রিয়া থাকে তবে এটি ক্লিনার হতে পারে, ডেকে বলুন যা vprintআপনার জন্য ভার্বোজের পতাকাটি পরীক্ষা করে। তারপরে আপনি আপনার নিজের vprintফাংশনটিকে যে কোনও জায়গায় call চ্ছিক ভার্বোসটি বলতে চান।


2

আমি চুরি লগিং কোড থেকে virtualenv খনি একটি প্রকল্পের জন্য। অল্পক্ষণের main()এর virtualenv.pyদেখতে কিভাবে এটি সক্রিয়া হচ্ছে। কোড সহ সিঁচিত হয় logger.notify(), logger.info(), logger.warn(), এবং মত। কোন পদ্ধতি আসলে নির্গত আউটপুট দ্বারা কিনা virtualenv সঙ্গে চালানো হয়েছিল নির্ধারণ করা হয় -v, -vv, -vvv, অথবা -q


2

@ কিন্ডলের সমাধানটি আমার পাইথন সংস্করণ 3.5 এর সাথে কাজ করে না। @ স্টাইলগুলি তার মন্তব্যে সঠিকভাবে জানিয়েছে যে কারণটি অতিরিক্ত alচ্ছিক কীওয়ার্ড যুক্তি। অতএব পাইথন 3 এর জন্য আমার সামান্য পরিশ্রুত সংস্করণটি এর মতো দেখাচ্ছে:

if VERBOSE:
    def verboseprint(*args, **kwargs):
        print(*args, **kwargs)
else:
    verboseprint = lambda *a, **k: None # do-nothing function

1

একটি বৈশ্বিক পরিবর্তনশীল হতে পারে, সম্ভবত সেট দিয়ে সেট করা argparseহয়েছে sys.argv, এটি প্রোগ্রামটি ভার্বোস হওয়া উচিত কিনা তা বোঝায়। তারপরে কোনও সাজসজ্জারকে এমন লেখা যেতে পারে যে যদি ভার্বোসিটি চালু থাকে, তবে ফাংশনটি চালানোর সময় পর্যন্ত স্ট্যান্ডার্ড ইনপুটটি নাল ডিভাইসে ডাইভার্ট করা হবে:

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")

এই উত্তরটি এই কোড দ্বারা অনুপ্রাণিত ; আসলে, আমি এটি কেবলমাত্র আমার প্রোগ্রামে একটি মডিউল হিসাবে ব্যবহার করতে যাচ্ছিলাম, কিন্তু আমি বুঝতে পারি না এমন ত্রুটি পেয়েছি, তাই আমি এর একটি অংশটি অভিযোজিত করেছি।

এই সমাধানটির খারাপ দিকটি হ'ল ভারবোসিটি দ্বিপাক্ষিক, এর বিপরীতে logging, যা প্রোগ্রামটি কীভাবে ভার্বোস হতে পারে তার সূক্ষ্ম-সুরকরণের অনুমতি দেয়। এছাড়াও, সমস্ত print কলগুলি ডাইরেক্ট করা হয়েছে, এটির জন্য অযাচিত হতে পারে।


0

আমার যা দরকার তা হ'ল একটি ফাংশন যা কোনও অবজেক্ট (ওজেক্ট) প্রিন্ট করে তবে কেবল যদি বৈশ্বিক চলক ভার্বোস সত্য হয়, অন্যথায় এটি কিছুই করে না।

আমি যে কোনও সময় গ্লোবাল প্যারামিটার "ভারবোজ" পরিবর্তন করতে সক্ষম হতে চাই। আমার কাছে সরলতা এবং পাঠযোগ্যতার গুরুত্ব বহুল importance সুতরাং আমি নিম্নলিখিত লাইনগুলি ইঙ্গিত হিসাবে অগ্রসর হবে:

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')
>>> 

প্যারামিটার তালিকা থেকেও গ্লোবাল ভেরিয়েবল "ভার্বোজ" সেট করা যায়।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.