Niedawno przeprowadziłem migrację do Py 3.5. Ten kod działał poprawnie w Pythonie 2.7:
with open(fname, 'rb') as f:
lines = [x.strip() for x in f.readlines()]
for line in lines:
tmp = line.strip().lower()
if 'some-pattern' in tmp: continue
# ... code
Po aktualizacji do wersji 3.5 otrzymuję:
TypeError: a bytes-like object is required, not 'str'
błąd w ostatnim wierszu (kod wyszukiwania wzoru).
Próbowałem użyć .decode()
funkcji po obu stronach instrukcji, próbowałem też:
if tmp.find('some-pattern') != -1: continue
- bez skutku.
Byłem w stanie szybko rozwiązać prawie wszystkie problemy 2: 3, ale to małe stwierdzenie mnie wkurza.
result = requests.get
i staram sięx = result.content.split("\n")
. Jestem trochę zdezorientowany komunikatem o błędzie, ponieważ wydaje się sugerować, żeresult.content
jest to ciąg znaków i.split()
wymaga obiektu podobnego do bajtów. („wymagany jest obiekt podobny do bajtów, a nie„ str ””) ..Odpowiedzi:
Plik otworzyłeś w trybie binarnym:
Oznacza to, że wszystkie dane odczytane z pliku są zwracane jako
bytes
obiekty, a niestr
. Nie można wtedy użyć ciągu w teście ograniczającym:Zamiast tego musisz użyć
bytes
obiektu do przetestowaniatmp
:lub zamiast tego otwórz plik jako plik tekstowy, zastępując
'rb'
tryb na'r'
.źródło
'r'
vs'rb'
też , przełączanie pomiędzy binarne i tekstowe zachowań plików (jak tłumaczeniu nowej linii i na niektórych platformach, jak znacznik EOF jest traktowany). To, żeio
biblioteka (zapewniająca domyślną funkcjonalność I / O w Pythonie 3, ale także dostępna w Pythonie 2) teraz domyślnie dekoduje pliki tekstowe, jest prawdziwą zmianą.'b'
flagi tylko wtedy, gdy musiałem pracować z plikami binarnymi w systemie DOS / Windows (ponieważ plik binarny jest domyślny POSIX). Dobrze, że w celuio
uzyskania dostępu do plików ma zastosowanie podwójny cel .Możesz zakodować swój ciąg za pomocą
.encode()
Przykład:
źródło
Jak już wspomniano, czytasz plik w trybie binarnym, a następnie tworzysz listę bajtów. W poniższej pętli for porównujesz ciąg znaków do bajtów i właśnie tam kod zawiedzie.
Dekodowanie bajtów podczas dodawania do listy powinno działać. Zmieniony kod powinien wyglądać następująco:
Typ bajtów został wprowadzony w Pythonie 3 i dlatego twój kod działał w Pythonie 2. W Pythonie 2 nie było typu danych dla bajtów:
źródło
Musisz zmienić z wb na w:
do
Po zmianie tego błędu znika, ale nie możesz zapisać do pliku (w moim przypadku). W końcu nie mam odpowiedzi?
Źródło: Jak usunąć ^ M
Zmiana na „rb” powoduje drugi błąd: io.UnsupportedOperation: write
źródło
dla tego małego przykładu: importuj gniazdo
dodanie litery „b” przed „GET http://www.py4inf.com/code/romeo.txt HTTP / 1.0 \ n \ n” rozwiązało mój problem
źródło
Użyj funkcji encode () wraz z zakodowaną wartością ciągu podaną w jednym cudzysłowie.
Dawny:
LUB
źródło
Plik otworzyłeś w trybie binarnym:
Poniższy kod spowoduje wygenerowanie błędu typu: wymagany jest obiekt podobny do bajtu, a nie „str”.
Działa następujący kod - musisz użyć funkcji decode ():
źródło
dlaczego nie spróbować otworzyć pliku jako tekst?
Dodatkowo tutaj jest link do Pythona 3.x na oficjalnej stronie: https://docs.python.org/3/library/io.html A to jest funkcja otwarta: https://docs.python.org/3 /library/functions.html#open
Jeśli naprawdę próbujesz traktować go jako plik binarny, rozważ kodowanie łańcucha.
źródło
Wystąpił ten błąd, gdy próbowałem przekonwertować znak (lub ciąg znaków)
bytes
, kod był podobny do tego w Pythonie 2.7:Tak działa Python 2.7 w przypadku znaków Unicode.
To nie będzie działać z Pythonem 3.6, ponieważ
bytes
wymaga dodatkowego argumentu do kodowania, ale może to być trochę trudne, ponieważ różne kodowanie może dawać różne wyniki:W moim przypadku musiałem użyć
iso_8859_1
kodowania bajtów, aby rozwiązać problem.Mam nadzieję, że to komuś pomoże.
źródło