Возможность концепции оператора присваивания для метода объекта
Позволять: a = 5
, b = 10
, а также hello_world = 'Hello World'
,
Насколько я понимаю: Python позволяет нам использовать операторы присваивания, чтобы нам не пришлось повторять левый операнд. Например, a = a + b
может быть переписан как a += b
где оба вернутся 15
,
Так что с некоторыми объектами Python это может быть несколько похоже, в зависимости от того, что возвращает вызываемый метод.
Со строкой, str
или в этом случае наша строка hello_world
Есть множество методов, которые вы можете использовать для его изменения, например: hello_world.lower()
и иногда я бы назвал это, чтобы присвоить переменной результат метода внутри. Например, hello_world = hello_world.lower()
может быть переписан как что-то вроде hello_world .= lower()
где оба вернутся hello world
,
Есть ли что-нибудь подобное в Python? Это абсолютно абсурдно или смущает вас? Любопытно, что люди думают об этом и / или если это уже существует.
2 ответа
Есть ли что-нибудь подобное в Python?
нет
Это абсолютно абсурдно или смущает вас?
При этом, это будет несколько отличаться от существующих операторов расширенного присваивания (например, +=
, *=
, так далее.). Для этих операторов вы можете определить специальный магический метод (__iadd__
, __imul__
и т. д.) для их реализации. Ключевой особенностью этого является то, что, поскольку вызывается отдельный метод, они могут обновить объект на месте. Например, если x
это список, то x += [1, 2, 3]
будет на самом деле мутировать объект x
вместо создания нового списка.
Для вашего предложенного .=
Оператор, не ясно, как это может работать. Если бы был __imeth__
оператор для "расширенного назначения метода", что бы он взял в качестве аргументов? Если бы в качестве аргумента использовалось имя метода, вам понадобился бы гигантский блок if внутри __imeth__
решить, что делать для различных методов (т. е. if method == 'lower'
обрабатывать .lower()
и так далее). Если он не принимает имя метода в качестве аргумента, как он узнает, какой метод вызывается?
Более важно, однако, что фундаментальная особенность существующих операторов заключается в том, что они принимают выражение в качестве своих операндов. С вашим предложенным .=
что бы случилось, если бы ты сделал x .= 3
? Или же x .= (foo+bar).blah()/7
? Или даже x .= lower
(без скобок)? Казалось бы, что .=
потребовал бы, чтобы его правый аргумент был синтаксически ограничен только одним вызовом функции (который интерпретировался бы как вызов метода). Это сильно отличается от любого существующего оператора Python.
Похоже, что единственный способ справиться со всем этим - это уменьшить объем предложения, чтобы оно действительно принимало только один вызов функции справа, и сделать его не настраиваемым, чтобы x .= method(...)
чистый синтаксический сахар для x = x.method(...)
, Но, как описано выше, это намного слабее, чем позволяет текущее расширенное назначение, поэтому я не думаю, что это будет большой победой.
Вы думаете об увеличенных назначениях, это утверждения, которые нельзя расширять.
Расширенные назначения охватывают только двоичные операторы (в частности, степенные, двоичные арифметические, сдвиговые и двоичные побитовые операторы). Синтаксис ссылки на атрибут не является оператором, двоичным или иным образом. Таким образом, нет расширенного присваивания "оператор-атрибут".
Обратите внимание, что я не охватил синтаксис вызова; вы в основном говорите об атрибутах; что ты также называешь str.lower()
отдельно от поиска атрибутов.
Если вы считаете, что эта функция крайне упущена, я предлагаю вам внести ее в список рассылки Python Ideas, где обсуждаются возможные новые языковые функции.
Примите во внимание, что смысл расширенных назначений заключается в том, что они предоставляют возможность оптимизировать обновления на месте; они не просто синтаксический сахар. Для списков, например, listobj += iterable_of_values
это не то же самое, что listobj = listobj + iterable_of_values
, это на самом деле выполняет listobj.extend(iterable_of_values)
(и связывает имя listobj
вернуться к listobj
, что может привести к удивительному поведению. Для доступа к атрибутам такой возможности нет; атрибуты возвращают упомянутое имя, они не могут обновить что-либо на месте, если только вы не начнете злоупотреблять протоколом дескриптора, который вряд ли поддается интуитивному расширению.
Возможно, вы захотите прочитать оригинальное предложение по улучшению Python, в котором представлены расширенные назначения для языка; прежде чем вы сделаете это предложение, особенно необходимо прочитать раздел обоснования.