Ostatecznie różnica między try, excepttestowaniem a testowaniem len(sys.argv)nie jest aż tak znacząca. W porównaniu z nimi oba są nieco hakerskie argparse.
Wydaje mi się to jednak - jako swego rodzaju argument niskobudżetowy:
Możesz nawet użyć go do wygenerowania a namedtuplez wartościami domyślnymi None- wszystko w czterech wierszach!
Arg_list= collections.namedtuple('Arg_list', arg_names)
args =Arg_list(*(args.get(arg,None)for arg in arg_names))
Jeśli nie jesteś zaznajomiony z tym namedtuple, jest to po prostu krotka, która działa jak obiekt, umożliwiając dostęp do jego wartości za pomocą tup.attributeskładni zamiast tup[0]składni.
Więc pierwsza linia tworzy nowy namedtupletyp z wartościami dla każdej z wartości w arg_names. Druga linia przekazuje wartości ze argssłownika, używając getdo zwrócenia wartości domyślnej, gdy podana nazwa argumentu nie ma skojarzonej wartości w słowniku.
Coraz bardziej kocham Pythona, wszystko dzięki takim odpowiedziom i oczywiście przepełnieniu stosu! Szkoda, że nie mamy wyjaśnienia ostatnich dwóch wierszy. Uważam, że dla początkujących byłoby świetnie.
Goujon
2
Kocham to! Z łatwością najlepsze rozwiązanie tego problemu, jakie widziałem. Dla innych: nie było dla mnie od razu oczywiste (newb), że: 1) „polecenie” będzie za każdym razem przekazywane jako pierwszy argument i 2) wyniki można wywoływać za pomocą argumentów [0] itd.
Matt D
To na pewno fajne, ale co jest hackem w testowaniu długości?
colorlace
1
@timwiz Mówiłem tylko w porównaniu do używania argparse. Mimo to obecnie kopie się za każdym razem, gdy wracam do starego scenariusza i stwierdzam, że nie używałem argparse.
nadawca
117
Sprawdź długość sys.argv:
if len(sys.argv)>1:
blah = sys.argv[1]else:
blah ='blah'
Niektórzy wolą zaproponowane przez Ciebie podejście oparte na wyjątkach (np. try: blah = sys.argv[1]; except IndexError: blah = 'blah'), Ale nie podoba mi się to tak bardzo, ponieważ nie „skaluje się” prawie tak dobrze (np. Gdy chcesz zaakceptować dwa lub trzy argumenty) i może potencjalnie ukryć błędy (np. jeśli użyłeś blah = foo(sys.argv[1]), ale foo(...)wywołałeś IndexError, IndexErrorto zostanie zignorowane).
Dopóki jednak jesteś atomowy, nie ma się czym martwić try, except. Po prostu poczekaj na fooswój argument do elseklauzuli.
nadawca
3
Ponadto, kiedy myślisz o skalowaniu, czas przejść do argparse.
nadawca
1
+1 w argparse. Mam argparse.pywszystkie moje projekty wiersza poleceń.
David Wolever,
2
@senderle: jasne, jeśli jesteś pilny, to w porządku. Ale z mojego doświadczenia trywynika, że większość programistów nie jest sumienna i umieszcza całą logikę w klauzuli… Więc biorąc pod uwagę, że nie jest to trudniejsze (i IMO, trochę ładniejsze), wolę po prostu sprawdzić długość (również unikasz posiadania ludzi krzyczą na ciebie za używanie wyjątków do kontroli przepływu).
David Wolever,
2
@David, tak, rozumiem twój punkt widzenia. Muszę tryprzyznać, że jestem trochę apologetą. Po prostu czuję, że czasami jaśniej wyraża moje zamiary niż ifstwierdzenie.
senderle
22
Innym sposobem, którego jeszcze nie widziałem na liście, jest ustawienie wartości wartowniczej z wyprzedzeniem. Ta metoda wykorzystuje leniwą ocenę języka Python, w której nie zawsze musisz podawać elseinstrukcję. Przykład:
Najładniejsza jest dla mnie odpowiedź operatora trójskładnikowego. Siedzę tutaj cicho przeklinając fakt, że część oprogramowania, które utrzymuję, jest powiązana z Pythonem 2.4, który go nie ma.
Nie chodzi o sprawdzenie, czy zdefiniowano. Bardziej przypomina określenie, czy istnieje, co nie jest tym samym. Użyłem tego również do przypisywania zmiennych rezerwowych, ale nie jest to odpowiedź na aktualne pytanie.
m3nda
@ erm3nda Mogę usunąć startingpointzmienną z przykładu, ale pytanie dotyczy przypisania zmiennej rezerwowej, więc zrobiłem to samo.
anatoly techtonik
1
Jeśli ją usuniesz, pojawi się błąd dotyczący niezdefiniowanej zmiennej. Przeczytałem ponownie pytanie i to czego się spodziewa to zmienna zamiana :) więc jest ok. Dziękuję za radę w tej krótkiej drodze, jeśli sys.argv[1:]:. Działa to z argumentami pozycyjnymi, podczas gdy count nie.
m3nda
10
To zwykła lista w Pythonie. Wyjątkiem, który można by złapać w tym przypadku, jest IndexError, ale zamiast tego lepiej po prostu sprawdzić długość.
if len(sys.argv)>=2:
startingpoint = sys.argv[1]else:
startingpoint ='blah'
dla tych, którzy przegłosowali mnie, wstydź się, że nie wyjaśniłeś błędu.
Hassan Abdul-Kareem
Myślę, że to dlatego, że jest hackerski. Co jeśli ktoś przekaże SomeString jako argument? Jak tego użyć, jeśli możesz przyjąć, powiedzmy od 1 do 5 argumentów?
pbogut
Fajne (ale wciąż hakerskie) do ustawiania wartości domyślnej na wypadek, gdyby użytkownik nie podał argumentu. Po prostu dołącz, a następnie użyj argv [1].
Felizett
1
Całkiem blisko tego, co próbował zrobić pomysłodawca. Oto funkcja, której używam:
Odpowiedzi:
Ostatecznie różnica między
try, except
testowaniem a testowaniemlen(sys.argv)
nie jest aż tak znacząca. W porównaniu z nimi oba są nieco hakerskieargparse
.Wydaje mi się to jednak - jako swego rodzaju argument niskobudżetowy:
Możesz nawet użyć go do wygenerowania a
namedtuple
z wartościami domyślnymiNone
- wszystko w czterech wierszach!Jeśli nie jesteś zaznajomiony z tym
namedtuple
, jest to po prostu krotka, która działa jak obiekt, umożliwiając dostęp do jego wartości za pomocątup.attribute
składni zamiasttup[0]
składni.Więc pierwsza linia tworzy nowy
namedtuple
typ z wartościami dla każdej z wartości warg_names
. Druga linia przekazuje wartości zeargs
słownika, używającget
do zwrócenia wartości domyślnej, gdy podana nazwa argumentu nie ma skojarzonej wartości w słowniku.źródło
Sprawdź długość
sys.argv
:Niektórzy wolą zaproponowane przez Ciebie podejście oparte na wyjątkach (np.
try: blah = sys.argv[1]; except IndexError: blah = 'blah'
), Ale nie podoba mi się to tak bardzo, ponieważ nie „skaluje się” prawie tak dobrze (np. Gdy chcesz zaakceptować dwa lub trzy argumenty) i może potencjalnie ukryć błędy (np. jeśli użyłeśblah = foo(sys.argv[1])
, alefoo(...)
wywołałeśIndexError
,IndexError
to zostanie zignorowane).źródło
try, except
. Po prostu poczekaj nafoo
swój argument doelse
klauzuli.argparse
.argparse.py
wszystkie moje projekty wiersza poleceń.try
wynika, że większość programistów nie jest sumienna i umieszcza całą logikę w klauzuli… Więc biorąc pod uwagę, że nie jest to trudniejsze (i IMO, trochę ładniejsze), wolę po prostu sprawdzić długość (również unikasz posiadania ludzi krzyczą na ciebie za używanie wyjątków do kontroli przepływu).try
przyznać, że jestem trochę apologetą. Po prostu czuję, że czasami jaśniej wyraża moje zamiary niżif
stwierdzenie.Innym sposobem, którego jeszcze nie widziałem na liście, jest ustawienie wartości wartowniczej z wyprzedzeniem. Ta metoda wykorzystuje leniwą ocenę języka Python, w której nie zawsze musisz podawać
else
instrukcję. Przykład:Lub jeśli zamierzasz składać CRAZY, możesz użyć potrójnego operatora Pythona :
źródło
Używam tego - nigdy nie zawodzi:
źródło
startingpoint
zmienną z przykładu, ale pytanie dotyczy przypisania zmiennej rezerwowej, więc zrobiłem to samo.sys.argv[1:]:
. Działa to z argumentami pozycyjnymi, podczas gdy count nie.To zwykła lista w Pythonie. Wyjątkiem, który można by złapać w tym przypadku, jest IndexError, ale zamiast tego lepiej po prostu sprawdzić długość.
źródło
Rozwiązanie działające z wbudowaną funkcją mapy!
Następnie wystarczy wywołać parametry w ten sposób:
źródło
Możesz po prostu dodać wartość argv [1] do argv, a następnie sprawdzić, czy argv [1] nie jest równe wprowadzonemu łańcuchowi Przykład:
źródło
Całkiem blisko tego, co próbował zrobić pomysłodawca. Oto funkcja, której używam:
Tak więc użycie byłoby takie jak:
źródło