Я пытаюсь написать небольшой класс и хочу отсортировать предметы по весу. Код предоставляется,
class Bird:
def __init__(self, weight):
# __weight for the private variable
self.__weight = weight
def weight(self):
return self.__weight
def __repr__(self):
return "Bird, weight = " + str(self.__weight)
if __name__ == '__main__':
# Create a list of Bird objects.
birds = []
birds.append(Bird(10))
birds.append(Bird(5))
birds.append(Bird(200))
# Sort the birds by their weights.
birds.sort(lambda b: b.weight())
# Display sorted birds.
for b in birds:
print(b)
Когда я запускаю программу, я получаю стек ошибок Python TypeError: sort() takes no positional arguments. В чем проблема?






Именно то, что он говорит: sort не принимает никаких позиционных аргументов. Он принимает аргумент, состоящий только из ключевого слова, с именем key:
birds.sort(key=lambda b: b.weight())
Из документация:
sort(*, key=None, reverse=False)
This method sorts the list in place, using only
<comparisons between items. Exceptions are not suppressed - if any comparison operations fail, the entire sort operation will fail (and the list will likely be left in a partially modified state).
sort()accepts two arguments that can only be passed by keyword (keyword-only arguments):key specifies a function of one argument that is used to extract a comparison key from each list element (for example,
key=str.lower). The key corresponding to each item in the list is calculated once and then used for the entire sorting process. The default value ofNonemeans that list items are sorted directly without calculating a separate key value.[...]
* в подписи — это разделитель между позиционными параметрами и параметрами, содержащими только ключевые слова; его положение в качестве начального «аргумента» указывает на отсутствие позиционных параметров.
Этому есть историческая причина. В раннем питоне ожидалась cmp-функция. В какой-то момент была добавлена возможность передавать ключевую функцию, а не cmp-функцию. В python3 убрана возможность передачи cmp-функции. Чтобы убедиться, что старые python2-скрипты (передача cmp-функции в качестве позиционного аргумента) не сломаются с еще более неясной ошибкой, sort больше не принимает позиционный аргумент.
Глядя на документацию для list.sort, мы видим, что key — это аргумент, состоящий только из ключевых слов. Так что меняйте строчку
birds.sort(lambda b: b.weight())
к
birds.sort(key=(lambda b: b.weight()))
Однако вам не нужны скобки для ключа. просто key=lambda b: b.weight() будет достаточно.
@ alec935 Прошу не согласиться. Просто взгляните на ответ Чепнера. Так намного легче читать без лишних скобок, и это делает то же самое. Если OP имеет больше кода, вложенного перед sort, сколько закрывающих скобок слишком много?
sort() принимает аргумент key и ничего больше (ну, может принимать аргумент reverse). Вы предоставили sort() аргумент, который он не может принять. Просто добавьте key= перед lambda
Сообщение об ошибке связано с тем, что key принимает аргументы ключевого слова, а не позиционные аргументы. Позиционный аргумент — это имя, за которым не следует знак равенства и значение по умолчанию.
Эта ошибка на самом деле специфична для python3. Python2 предположил бы, что функция, заданная для сортировки, является функцией cmp. Приведенный выше код все равно сломается, поскольку вы даете ему ключевую функцию. Я нашел этот вопрос, потому что мой скрипт python2 сломался при работе под python3.