Python: определение собственных операторов?

80

Я хотел бы определить своего оператора. Поддерживает ли Python такое?

cwj
источник
Что ж, у вас может быть оператор, который не определен (например, $), а затем использовать некоторый код Python для редактирования самого себя (с open) и изменения всего a $ bнаfunction(a,b)
whackamadoodle3000

Ответы:

40

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

Зифре
источник
1
См. Ниже набор предопределенных переопределяемых операторов Python.
Палимондо
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 01
79
@DasIch Я не могу не согласиться. Не все мы можем сознательно выбирать язык. С другой стороны, я не понимаю, почему я должен соглашаться с чужими дизайнерскими решениями, если я не удовлетворен. - Действительно отличный хак!
ThomasH
+1 Для очень крутого хака, но мой вопрос был больше о том, является ли определение моих собственных операторов функцией в Python или нет, а не о том, можно ли имитировать наличие новых операторов, и, похоже, ответ - нет, вы не можете определить новые операторы. Хотя это чертовски близко.
ArtOfWarfare
2
Я просто совмещал это с pipeот toolz. pip = Infix(lambda x,y: pipe(x,y)). тогда 8 |pip| range |pip| sum |pip| range. вроде работает.
cantdutchth
44

Нет, Python поставляется с предопределенным, но переопределяемым набором операторов .

DFA
источник
1
Мне любопытно узнать, как dfplyиспользует -->оператор: todatascience.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 и этот билет отслеживания улучшений для получения дополнительной информации.

billyjmc
источник
10

Если вы намереваетесь применить операцию к определенному классу объектов, вы можете просто переопределить ближайший к вашей функции оператор ... например, переопределение __eq__()переопределит ==оператор и вернет все, что вы хотите. Это работает практически для всех операторов.

Судхир Джонатан
источник
9

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

PEP465 представил этот новый оператор для матричного умножения, чтобы упростить запись многих числовых кодов. Оператор будет реализован не для всех типов, а только для объектов, подобных массивам.

Вы можете поддержать оператор для своих классов / объектов, реализовав __matmul__().

PEP оставляет место для другого использования оператора для объектов, не похожих на массивы.

Конечно, вы можете реализовать @любую операцию, отличную от умножения матриц, также для объектов, подобных массивам, но это повлияет на взаимодействие с пользователем, потому что все будут ожидать, что ваш тип данных будет вести себя по-другому.

gg349
источник
Вы просто имеете в виду, что @это новый символ оператора? Или что мы можем как-то использовать его для определения новых собственных операторов?
Аддем
Да, @ - это новый символ оператора. Да, вы можете использовать его для определения операций с вашими объектами. Считайте чтение PEP465.
gg349 07
5
@Addem Он просто имел ввиду, что @это новый оператор. Вот и все. Факт остается фактом: в Python нельзя определять собственные операторы.
Джон Ред