TypeError: аргумент utf_8_encode () 1 должен быть str, а не байтами - PullRequest
0 голосов
/ 11 июля 2020

Я работаю над RESTful API в рамках обучения Udacity:

https://www.udacity.com/course/designing-restful-apis--ud388

Я получил стартовый код ( find_restaurant.py ) и задание - заполнить этот код. Я пытаюсь выполнить этот код шаг за шагом.

Когда я запускаю: "find_restaurant.py", он возвращает следующую трассировку.

Я искал inte rnet (включая переполнение стека) и нашел несколько соответствующих тем, однако я не понимаю, в чем проблема. Может ли кто-нибудь помочь мне понять TypeError?

Traceback (most recent call last):

  File "D:\ds_dev\Udacity\fullstack-nanodegree-vm\find_restaurant.py", line 37, in <module>
    find_restaurant("Pizza", "Tokyo, Japan")

  File "D:\ds_dev\Udacity\fullstack-nanodegree-vm\find_restaurant.py", line 23, in find_restaurant
    print(meal_type)

  File "C:\Users\zeerm\.conda\envs\spyder\lib\codecs.py", line 378, in write
    self.stream.write(data)

  File "C:\Users\zeerm\.conda\envs\spyder\lib\codecs.py", line 377, in write
    data, consumed = self.encode(object, self.errors)

TypeError: utf_8_encode() argument 1 must be str, not bytes

geocode.py:

import json
import httplib2


def geocode_location(address_string):
    """Retrieve latitude and longitude for a location string.

    Http GET request to Google Maps API for retrieving latitude and longitude
    for a location string.
    """
    
    address = address_string.replace(" ", "%20")
    key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
    url = (f'https://maps.googleapis.com/maps/api/geocode/json?' +
           f'address={address}&key={key}')
    h = httplib2.Http()
    result = json.loads(h.request(url, 'GET')[1])
    latitude = result['results'][0]['geometry']['location']['lat']
    longitude = result['results'][0]['geometry']['location']['lng']
    return (latitude, longitude)

find_restaurant.py

import json
import sys
import codecs
import httplib2
from geocode import geocode_location

sys.stdout = codecs.getwriter('utf8')(sys.stdout)
sys.stderr = codecs.getwriter('utf8')(sys.stderr)

FOURSQUARE_CLIENT_ID = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
FOURSQUARE_CLIENT_SECRET = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

def find_restaurant(meal_type, location):
    """ # TODO: Descripe function."""

    # 1. Use getGeocodeLocation to get the latitude and longitude coordinates of the location string.
    print(meal_type)
    lat_lng = geocode_location(location)
    print(lat_lng)
    # 2.  Use foursquare API to find a nearby restaurant with the latitude, longitude, and mealType strings.
    # HINT: format for url will be something like https://api.foursquare.com/v2/venues/search?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&v=20130815&ll=40.7,-74&query=sushi

    # 3. Grab the first restaurant
    # 4. Get a  300x300 picture of the restaurant using the venue_id (you can change this by altering the 300x300 value in the URL or replacing it with 'orginal' to get the original picture
    # 5. Grab the first image
    # 6. If no image is available, insert default a image url
    # 7. Return a dictionary containing the restaurant name, address, and image url


if __name__ == '__main__':
    find_restaurant("Pizza", "Tokyo, Japan")
    find_restaurant("Tacos", "Jakarta, Indonesia")
    find_restaurant("Tapas", "Maputo, Mozambique")
    find_restaurant("Falafel", "Cairo, Egypt")
    find_restaurant("Spaghetti", "New Delhi, India")
    find_restaurant("Cappuccino", "Geneva, Switzerland")
    find_restaurant("Sushi", "Los Angeles, California")
    find_restaurant("Steak", "La Paz, Bolivia")
    find_restaurant("Gyros", "Sydney, Australia")

1 Ответ

0 голосов
/ 12 июля 2020

codecs.getwriter возвращает экземпляр codecs.StreamWriter , который обертывает поток и записывает в него, используя кодировку, переданную в getwriter. В коде в вопросе sys.stdout и sys.stderr обертываются средствами записи, которые будут записывать в них байты в кодировке UTF-8

sys.stdout = codecs.getwriter('utf8')(sys.stdout)
sys.stderr = codecs.getwriter('utf8')(sys.stderr)

Однако sys.stdout и sys.stderr - это text streams, поэтому их методы write ожидают str, а не Bytes. Поскольку StreamWriter передает байты, возникает исключение.

Переопределение sys.stdout, как это, метод, используемый в Python2 для принудительного выполнения определенной выходной кодировки при передаче по конвейеру.

In В данном конкретном случае эти две строчки следует удалить из кода. Если необходимо форсировать вывод в кодировке, отличной от кодировки по умолчанию, тогда лучше установить переменную среды PYTHONIOENCODING .

...