Czy Python ma coś w rodzaju pustej zmiennej łańcuchowej, w której możesz:
if myString == string.empty:
Niezależnie od tego, jaki jest najbardziej elegancki sposób sprawdzania pustych wartości ciągu? Za ""
każdym razem znajduję stałe kodowanie, aby sprawdzić pusty ciąg znaków nie tak dobry.
python
string
comparison-operators
Joan Venge
źródło
źródło
""
nie jest tak dobrze?Odpowiedzi:
Puste ciągi znaków są „fałszowane”, co oznacza, że są uważane za fałszywe w kontekście logicznym, więc możesz to po prostu zrobić:
Jest to preferowany sposób, jeśli wiesz, że twoja zmienna jest łańcuchem. Jeśli twoja zmienna może być również innego typu, powinieneś użyć
myString == ""
. Zobacz dokumentację dotyczącą testowania wartości prawdy, aby znaleźć inne wartości, które są fałszywe w kontekście boolowskim.źródło
if not myString:
blok jeślimyString
byłyNone
,0
,False
itd., Więc jeśli nie jesteś pewien, jakiego rodzajumyString
jest, należy użyćif myString == "":
w celu ustalenia, czy jest pusty ciąg znaków, w przeciwieństwie do jakaś inna wartość fałsz.if myString == ...
wyrażeń moglibyśmy użyćif myString in (None, '')
lub na @Bartek,if myString in (None, '') or not myString.strip()
Z PEP 8 w sekcji „Zalecenia dotyczące programowania” :
Więc powinieneś użyć:
lub:
Aby wyjaśnić, sekwencje są oceniane w
False
lubTrue
w kontekście logicznym, jeśli są puste, czy nie. Są nie równa sięFalse
lubTrue
.źródło
x == False
. Ale wyjaśnienie IMHO jest nadal mile widziane, biorąc pod uwagę grupę docelową.Najbardziej eleganckim sposobem byłoby prawdopodobnie sprawdzenie, czy jest to prawda czy fałsz, np .:
Możesz jednak usunąć białe znaki, ponieważ:
Prawdopodobnie powinieneś być w tym nieco bardziej wyraźny, chyba że wiesz na pewno, że ten łańcuch przeszedł pewną walidację i jest łańcuchem, który można przetestować w ten sposób.
źródło
Chciałbym przetestować jedność przed rozbiórką. Wykorzystałbym również fakt, że puste ciągi znaków są fałszywe (lub Falsy). To podejście jest podobne do StringUtils.isBlank Apache lub Strings.isNullOrEmpty Guava
Oto, czego użyłbym do przetestowania, jeśli łańcuch ma wartość Brak LUB Pusty LUB Pusty:
I dokładnie odwrotnie niż w przypadku testu, jeśli ciąg znaków nie jest Brak NOR Pusty NOR Pusty:
Bardziej zwięzłe formy powyższego kodu:
źródło
if mystring and not mystring.strip()
?string and not string.isspace()
?def isBlank(s): return not (s and s.strip())
idef isNotBlank(s): return s and s.strip()
.Kiedyś napisałem coś podobnego do odpowiedzi Bartka i inspirowałem się javascript:
Test:
źródło
return bool(s.strip())
AttributeError: 'NoneType' object has no attribute 'strip'
Jedyny naprawdę solidny sposób to zrobić:
Wszystkie inne rozwiązania mają możliwe problemy i przypadki brzegowe, w których sprawdzenie może się nie powieść.
len(myString)==0
może zawieść, jeślimyString
jest obiektem klasy, która dziedziczystr
i zastępuje__len__()
metodę.Podobnie
myString == ""
imyString.__eq__("")
może zawieść, jeślimyString
zastąpi__eq__()
i__ne__()
.Z jakiegoś powodu
"" == myString
daje się również zwieść, jeślimyString
zastąpi__eq__()
.myString is ""
i"" is myString
są równoważne. Oba zawiodą, jeśli wmyString
rzeczywistości nie jest łańcuchem, ale podklasą łańcucha (oba zwrócąFalse
). Ponadto, ponieważ są to kontrole tożsamości, jedynym powodem, dla którego działają, jest to, że Python używa String Pooling (zwanego również internacjonalizacją ciągu), który korzysta z tej samej instancji ciągu, jeśli jest internowany (patrz tutaj: Dlaczego porównywanie ciągów za pomocą albo '= = ”lub„ is ”czasami dają inny wynik? ). I""
jest internowany od samego początku w CPythonDużym problemem związanym z kontrolą tożsamości jest to, że internowanie ciągów jest (o ile mogłem znaleźć) tym, że nie jest ustandaryzowane, które ciągi są internowane. Oznacza to, że teoretycznie
""
nie jest konieczne internowanie i zależy to od implementacji.Jedynym sposobem na osiągnięcie tego, że tak naprawdę nie da się oszukać jedną wspomniałem na początku:
"".__eq__(myString)
. Ponieważ to jawnie wywołuje__eq__()
metodę pustego ciągu, nie można go oszukać przez przesłanianie jakichkolwiek metod w myString i solidnie działa z podklasamistr
.Również poleganie na falsyniczności łańcucha może nie działać, jeśli obiekt go przesłoni
__bool__()
metodę.Jest to nie tylko praca teoretyczna, ale może być istotna w rzeczywistym użyciu, ponieważ widziałem podklasy bibliotek i bibliotek
str
przed użyciemmyString is ""
może zwrócić tam niepoprawne dane wyjściowe.Również porównywanie ciągów za pomocą
is
ogólnie jest dość złą pułapką, ponieważ czasami działa poprawnie, ale nie w innym czasie, ponieważ pula ciągów znaków jest dość dziwna.To powiedziawszy, w większości przypadków wszystkie wymienione rozwiązania będą działać poprawnie. Ten post jest głównie pracą akademicką.
źródło
Przetestuj pusty lub pusty ciąg (krócej):
źródło
myString = None
spowoduje wyjątek. Lepsze wykorzystanie @ skarbca odpowiedźJeśli chcesz rozróżnić puste i puste ciągi, sugerowałbym użycie
if len(string)
, w przeciwnym razie sugerowałbym użycieif string
tak, jak powiedzieli inni. Zastrzeżenie dotyczące ciągów pełnych białych znaków ma jednak zastosowanie, więc nie zapomnij o tymstrip
.źródło
if stringname:
daje,false
gdy ciąg jest pusty. Myślę, że to nie może być prostsze niż to.źródło
źródło
a='a'
, otrzymasza.isspace() -> False
, alea
na tym koncie nie będzie pusty ciąg.Podejście do czystego kodu
Robienie tego:
foo == ""
jest bardzo złą praktyką.""
jest magiczną wartością. Nigdy nie powinieneś sprawdzać wartości magicznych (bardziej znanych jako liczby magiczne) )Co powinieneś zrobić, to porównać do opisowej nazwy zmiennej.
Opisowe nazwy zmiennych
Ktoś może pomyśleć, że „empty_string” to opisowa nazwa zmiennej. To nie jest .
Zanim pójdziesz i zrobisz
empty_string = ""
pomyślisz, że masz świetną nazwę zmiennej do porównania. Nie to znaczy „nazwa zmiennej opisowej”.Dobra nazwa zmiennej opisowej oparta jest na jej kontekście. Trzeba myśleć o tym, co pusty łańcuch jest .
Prosty przykład pola formularza
Budujesz formularz, w którym użytkownik może wprowadzać wartości. Chcesz sprawdzić, czy użytkownik coś napisał, czy nie.
Dobra nazwa zmiennej może być
not_filled_in
Dzięki temu kod jest bardzo czytelny
Dokładny przykład analizy CSV
Analizujesz pliki CSV i chcesz, aby pusty ciąg był analizowany jako
None
(Ponieważ CSV jest w całości oparty na tekście, nie może reprezentować
None
bez użycia wstępnie zdefiniowanych słów kluczowych)Dobra nazwa zmiennej może być
CSV_NONE
Ułatwia to zmianę i dostosowanie kodu, jeśli masz nowy plik CSV, który reprezentuje
None
inny ciąg niż""
Nie ma pytań, czy ten fragment kodu jest poprawny. Jest całkiem jasne, że robi to, co powinien.
Porównaj to z
Pierwsze pytanie brzmi: dlaczego pusty ciąg zasługuje na specjalne traktowanie?
Oznaczałoby to przyszłym programistom, że pusty ciąg powinien być zawsze uważany za
None
.Jest tak, ponieważ łączy logikę biznesową (jaka powinna być wartość CSV
None
) z implementacją kodu (z czym tak naprawdę porównujemy)Trzeba między nimi rozdzielić obawy .
źródło
""
nie jest magiczną wartością, taką samąTrue
,False
aniNone
nie jest magiczną wartością.Co powiesz na to? Być może nie jest to „najbardziej elegancki”, ale wydaje się dość kompletny i jasny:
źródło
Odpowiadanie na @ 1290. Przepraszamy, nie ma możliwości sformatowania bloków w komentarzach.
None
Wartość nie jest pusty ciąg znaków w Pythonie, i nie jest (ze spacjami). Odpowiedź z Andrew Clark jest prawidłowa:if not myString
. Odpowiedź @rouble jest specyficzna dla aplikacji i nie odpowiada na pytanie PO. Wpadniesz w kłopoty, jeśli przyjmiesz osobliwą definicję „pustego” ciągu. W szczególności, średnia zachowanie jest, żestr(None)
produkuje'None'
niepustego łańcucha.Jeśli jednak musisz traktować
None
i (spacje) jako „puste” ciągi, oto lepszy sposób:Przykłady:
Spełnia wymagania @rouble, nie przerywając oczekiwanego
bool
zachowania ciągów.źródło
python -c "if (str(None) == 'None'): print ('OMG, WHY ??')"
Uważam to za eleganckie, ponieważ upewnia się, że jest to sznurek i sprawdza jego długość:
źródło
-O
flagę lub ustawiszPYTHONOPTIMIZE
zmienną env.Innym łatwym sposobem może być zdefiniowanie prostej funkcji:
źródło
To wyrażenie ma wartość True dla ciągów, które są puste. Niepuste łańcuchy, Żaden i obiekty nie łańcuchowe będą generować False, z zastrzeżeniem, że obiekty mogą nadpisać __str__, aby udaremnić tę logikę, zwracając wartość fałszowania.
źródło
Możesz na to spojrzeć Przypisywanie pustej wartości lub łańcucha w Pythonie
Chodzi o porównywanie pustych ciągów. Zamiast testować pustkę
not
, możesz sprawdzić, czy łańcuch jest równy pustemu łańcuchowi z""
pustym łańcuchem ...źródło
dla tych, którzy oczekują zachowania jak apache StringUtils.isBlank lub Guava Strings.isNullOrEmpty :
źródło
Gdy czytasz plik po liniach i chcesz ustalić, która linia jest pusta, upewnij się, że użyjesz
.strip()
, ponieważ w wierszu „pustym” jest nowy znak linii:źródło
źródło
Jeśli tylko użyjesz
nie można odróżnić zmiennej boolean
False
od pustego łańcucha''
:Jeśli jednak dodasz prosty warunek do skryptu, różnica będzie następująca:
źródło
Jeśli jest to przydatne dla kogoś, oto szybka funkcja, którą zbudowałem, aby zastąpić puste ciągi znakami N / A na listach list (python 2).
Jest to przydatne do wysyłania list list do bazy danych mysql, która nie przyjmuje pustych pól dla niektórych pól (pola oznaczone w schemacie jako NN. W moim przypadku było to spowodowane złożonym kluczem podstawowym).
źródło
Przeprowadziłem pewne eksperymenty z ciągami takimi jak „”, „”, „\ n” itd. Chcę, aby właściwość NotNhitespace miała wartość True tylko wtedy, gdy zmienna foo jest łańcuchem z co najmniej jednym znakiem spacji. Używam Pythona 3.6. Oto, z czym skończyłem:
W razie potrzeby zawiń to w definicji metody.
źródło
Jak napisano powyżej, ale z pomyłką.
źródło
""
i" "
i fałsz dla"a"
(tak jak oczekiwano). Twój kod zwraca to samo, z wyjątkiem pustego ciągu zwraca True, czego nie powinien.