Python: визначення власних операторів?


80

Я хотів би визначити власного оператора. Чи підтримує Python таке?


Ну, у вас може бути оператор, який не визначений (на зразок $), а потім використовувати певний код python, щоб редагувати себе (за допомогою open) та змінити все a $ bнаfunction(a,b)
whackamadoodle3000

Відповіді:


40

Ні, ви не можете створювати нових операторів. Однак, якщо ви просто оцінюєте вирази, ви можете обробити рядок самостійно і обчислити результати нових операторів.


1
Див нижче для набору Пайтона з визначеного набору перевизначення операторів.
Палімондо

179

Хоча технічно ви не можете визначити нових операторів у Python, цей розумний хак працює навколо цього обмеження. Це дозволяє вам визначати оператори інфіксу таким чином:

# simple multiplication
x=Infix(lambda x,y: x*y)
print 2 |x| 4
# => 8

# class checking
isa=Infix(lambda x,y: x.__class__==y.__class__)
print [1,2,3] |isa| []
print [1,2,3] <<isa>> []
# => True

2
+1 Цей хак досить крутий, але я не думаю, що це спрацює в цій ситуації.
Zifre

9
Це може бути цікавий хак, але я не думаю, що це хороше рішення. Python не дозволяє створювати власні оператори, дизайнерське рішення, яке було прийнято з поважної причини, і ви повинні прийняти його, замість того, щоб сприймати це як проблему та винаходити шляхи її подолання. Це не гарна ідея боротися з мовою, на якій ви пишете код. Якщо ви дійсно хочете, вам слід використовувати іншу мову.
DasIch

79
@DasIch Я не міг не погодитися більше. Ми не всі можемо свідомо обирати мову. З іншого боку, я не розумію, чому мені слід погоджуватися з дизайнерськими рішеннями будь-кого іншого, якщо я не задоволений. - Насправді чудовий хак!
ThomasH

+1 Для дуже крутого злому, але моє запитання було більше про те, чи є визначення моїх власних операторів особливістю в Python чи ні, а не чи можна підробляти нових операторів, і, здається, відповідь - ні, ви не можете визначити нових операторів. Хоча це дійсно наближається.
ArtOfWarfare

2
Я просто поєднав це з pipeіз toolz. pip = Infix(lambda x,y: pipe(x,y)). тоді 8 |pip| range |pip| sum |pip| range. здається, працює.
кантдатч цього

44

Ні, Python постачається із заздалегідь визначеним, але переоцінюваним набором операторів .


1
Мені цікаво дізнатись, як dfplyвикористовується -->оператор: directiondatascience.com/…
Макс Кандокія

1
@MaxCandocia Наскільки я можу зрозуміти, це не так (див. Документи ). Прикладом у цій публікації, який використовує, -->здається, є пседокод. Сама бібліотека просто перевантажує >>.
Ендрю Маршалл,

11

Sage надає цю функціональність, по суті, використовуючи "розумний хак", описаний @Ayman Hourieh, але включений в модуль як декоратор, щоб надати більш чистий зовнішній вигляд та додаткову функціональність - ви можете вибрати оператора для перевантаження та, отже, порядок оцінки.

from sage.misc.decorators import infix_operator

@infix_operator('multiply')
def dot(a,b):
    return a.dot_product(b)
u=vector([1,2,3])
v=vector([5,4,3])
print(u *dot* v)
# => 22

@infix_operator('or')
def plus(x,y):
    return x*y
print(2 |plus| 4)
# => 6

Для отримання додаткової інформації дивіться документацію Sage та цей квиток для відстеження вдосконалення .


10

Якщо ви маєте намір застосувати операцію до певного класу об'єктів, ви можете просто перевизначити оператор, який відповідає вашій функції найближче ... наприклад, перевизначення __eq__()замінить ==оператора, щоб повернути все, що вам потрібно. Це працює майже для всіх операторів.


9

Python 3.5 вводить символ @для додаткового оператора.

PEP465 представив цей новий оператор для множення матриць, щоб спростити позначення багатьох числових кодів. Оператор буде реалізований не для всіх типів, а лише для масивів, подібних до об'єктів.

Ви можете підтримати оператор для своїх класів / об’єктів шляхом реалізації __matmul__().

PEP залишає простір для іншого використання оператора для об'єктів, не схожих на масиви.

Звичайно, ви можете реалізувати @будь-яку операцію, відмінну від множення матриць, також для об’єктів, подібних до масивів, але це вплине на взаємодію з користувачем, оскільки всі очікують, що ваш тип даних поводитиметься по-різному.


Ви просто маєте на увазі, що @це новий символ оператора? Або що ми якось можемо використати це для визначення власних нових операторів?
Аддем

Так, @ - це новий символ оператора. Так, ви можете використовувати його для визначення операцій над об’єктами. Подумайте про читання PEP465.
gg349

5
@Addem Він просто мав на увазі, що @це новий оператор. Це воно. Факт все ще залишається фактом: Ви не можете визначити власні оператори в Python.
Джон Ред
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.