Python: дефиниране на собствени оператори?

Бих искал да определя собствения си оператор. Python поддържа ли такова нещо?


person cwj    schedule 31.05.2009    source източник
comment
Е, можете да имате оператор, който не е дефиниран (като $) и след това да използвате някакъв код на Python, за да се редактирате (с open) и да промените всички a $ b на function(a,b)   -  person whackamadoodle3000    schedule 29.09.2017


Отговори (6)


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

person Zifre    schedule 31.05.2009
comment
Вижте по-долу за набора на Python от предварително дефинирани заменими набори от оператори. - person Palimondo; 20.05.2017

Въпреки че технически не можете да дефинирате нови оператори в 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
person Ayman Hourieh    schedule 31.05.2009
comment
+1 Този хак е доста готин, но не мисля, че ще работи в тази ситуация. - person Zifre; 31.05.2009
comment
Може да е интересен хак, но не мисля, че това е добро решение. Python не позволява създаването на собствени оператори, дизайнерско решение, което е взето с основателна причина и трябва да го приемете, вместо да виждате това като проблем и да измисляте начини да го заобиколите. Не е добра идея да се борите срещу езика, на който пишете кода. Ако наистина искате, трябва да използвате различен език. - person DasIch; 02.06.2009
comment
@DasIch Не мога да не се съглася повече. Не всички сме свободни да избираме съзнателно език. От друга страна, не виждам защо трябва да се примирявам с нечии други дизайнерски решения, ако не съм доволен. - Наистина отличен хак! - person ThomasH; 15.09.2010
comment
+1 За много готин хак, но въпросът ми беше по-скоро за това дали дефинирането на собствените ми оператори е функция в Python или не, а не дали е възможно да се фалшифицира, че има нови оператори, и изглежда, че отговорът е не, не можете дефинирайте нови оператори. Въпреки че това е доста близко. - person ArtOfWarfare; 12.06.2014
comment
Току-що комбинирах това с pipe от toolz. pip = Infix(lambda x,y: pipe(x,y)). след това 8 |pip| range |pip| sum |pip| range. изглежда работи. - person cantdutchthis; 31.07.2015
comment
Имайте предвид, че този хак ви ограничава до твърдо кодирания приоритет и асоциативността на стандартните оператори, с които злоупотребява. - person chepner; 25.03.2021
comment
Интересно решение, но може би това, което все пак го прави малко по-лошо от действителното дефиниране на оператор (което е невъзможно в Python без предварителна обработка на вашия код), е, че нямате достъп до аргументите, преди да бъдат оценени. Следователно не можете e. ж. дефинирайте свой собствен оператор за присвояване или ред за контролна оценка като оператора and. - person Yushin Washio; 16.05.2021

Не, Python идва с предварително дефиниран, но подлежащ на замяна, набор от оператори.

person dfa    schedule 31.05.2009
comment
Любопитен съм да разбера как dfply използва оператор -->: towardsdatascience.com/ - person Max Candocia; 30.04.2018
comment
@MaxCandocia Доколкото мога да кажа, не е (вижте документи). Примерът в тази публикация, който използва -->, изглежда е псевдокод. Самата библиотека просто претоварва >>. - person Andrew Marshall; 19.10.2018

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 и този билет за проследяване на подобрения за повече информация.

person billyjmc    schedule 18.12.2013

Ако възнамерявате да приложите операцията върху конкретен клас обекти, можете просто да замените оператора, който най-близко съответства на вашата функция... например, замяната на __eq__() ще замени оператора ==, за да върне каквото искате. Това работи за почти всички оператори.

person Sudhir Jonathan    schedule 31.05.2009

Python 3.5 въвежда символа @ за допълнителен оператор.

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

Можете да поддържате оператора за вашите класове/обекти, като имплементирате __matmul__().

PEP оставя място за различно използване на оператора за обекти, които не са подобни на масиви.

Разбира се, можете да приложите с @ всякакъв вид операция, различна от умножението на матрици, също и за обекти, подобни на масиви, но потребителското изживяване ще бъде засегнато, защото всеки ще очаква вашият тип данни да се държи по различен начин.

person gg349    schedule 09.01.2015
comment
Искате да кажете само, че @ е символ на нов оператор? Или че можем по някакъв начин да го използваме, за да дефинираме нови наши собствени оператори? - person Addem; 07.02.2016
comment
Да, @ е нов символ на оператора. Да, можете да го използвате, за да дефинирате операции върху вашите обекти. Помислете да прочетете PEP465. - person gg349; 07.02.2016
comment
@Addem Той просто имаше предвид, че @ е нов оператор. Това е. Фактът все още остава: не можете да дефинирате собствени оператори в Python. - person John Red; 24.03.2016