简体   繁体   中英

how do I define my own prefix and postfix operators in python

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?

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM