2

This question is an extension of a previous question (Python: defining my own operators?). I really liked the solution provided there for Infix operators, but for my expressions, I need a way to define custom unary operators in a similar fashion.

Do you have any recommendations? Reusing the existing python operators doesn't help, as I've used them all up. Thank you very much for your help!

The main reason for doing this overloading is the absence of the following unary operators in Python: (Is > 0) (Is >= 0) I need operators to distinguish between these two types of operations and my requirement is to match my interface as closely as possible with the interface provided by a pre-defined language which comes with its own set of operators. I could have chosen to replace the operators with > 0 and >= 0 but this did not go down very well with the user community. Is there a better way to do this?

Community
  • 1
  • 1
patris
  • 21
  • 3
  • 1
    I think it's a bad idea in general... Python advocates explicit over implicit, and obvious over magic. – Erik Kaplun Nov 06 '13 at 17:38
  • The main reason for doing this overloading is the absence of the following unary operators in Python: – patris Nov 07 '13 at 13:58

1 Answers1

2

Well you can use the same hack:

#! /usr/bin/python3.2

class Postfix:
    def __init__(self, f):
        self.f = f

    def __ror__(self, other):
        return self.f(other)

x = Postfix(lambda x: x * 2)

a = 'Hello'
print(a |x)
a = 23
print(a |x |x)

Nevertheless, I wouldn't advocate its use, as it is only confusing.

EDIT: Especially as your operators are unary, you can simply call a function, and anyone reading your code would understand immediately what it does.

def choose(t): pass
    #magic happens here and returns nCr(t[0], t[1])

nCr = Postfix(choose)

#This is unintuitive:
print((3, 4) |nCr)

nCr = choose

#But this is obvious:
print(nCr((3, 4)))

Edit2: Dear people who are religious about PEP-8: This "operator"-hack is all about not complying with PEP-8, so please stop editing the answer. The idea is that |op is read like one entity, basically a postfix operator.


Edit 3: Thinking hard about a case where this hack could come in handy, maybe the following could be a halfway sensible use. (If and only if this feature is well documented in the API):

#! /usr/bin/python3.2

class Language:
    def __init__(self, d):
        self.d = d

    def __ror__(self, string):
        try: return self.d[string]
        except: return string

enUS = Language({})
esMX = Language({'yes': 'sí', 'cancel': 'cancelar'})
deDE = Language({'yes': 'ja', 'no': 'nein', 'cancel': 'abbrechen'})

print('yes' |enUS)
print('no' |deDE)
print('cancel' |esMX)
Hyperboreus
  • 31,997
  • 9
  • 47
  • 87
  • Re: Edit2: the snippets for full of extraneous space not related to postfix; as to the postfix part—you're right and I apologise. – Erik Kaplun Nov 06 '13 at 17:39
  • @ErikAllik I have applied now PEP-8 where it is useful, and omitted it where it is senseless in this specific case. I hope it finds your acceptance. – Hyperboreus Nov 06 '13 at 17:41
  • yeah, definitely; no need for the subtle sarcasm; I was just trying to make the snippets more readable because the unusual overwhelming white space was making it harder to read. – Erik Kaplun Nov 06 '13 at 17:44
  • @ErikAllik And I fully agree with your comment to OP's question. But maybe OP has some justified needs for fake postfix operators, hence the proposed (and discouraged) hack. No sarcasm intended. – Hyperboreus Nov 06 '13 at 17:45
  • Yeah, agreed; that's why I added the "in general". – Erik Kaplun Nov 06 '13 at 17:46
  • why is this postfix notation considered confusing? It is standard in Mathematica and allows easy editing of code especially when applying multiple functions on an input. This is one of the features I miss the most from Mathematica – userrandrand May 11 '23 at 07:50