-2

Possible Duplicate:
Understanding Python decorators

Just trying to "port" some Python code to Java, I came then across the following python code:

 @fake(lambda s, t, n: [(s.field(i+1), s) for i in range(n)])
 def split(secret, threshold, num_players):
     shares = []
     for i in range(1, num_players+1):
         # do some shares calculation
     return shares

There are quite some interesting constructs in this one that I never noticed before. Could anyone tell me what is the deal with this @fake thingy?

def fake(replacement):
    """Replace a function with a fake version."""
    def decorator(func):
        fakes = os.environ.get('FUNC_FAKE', '')
        if fakes == '*' or func.__name__ in fakes.split():
            return replacement
        else:
            return func
    return decorator

Further, does this lambda stand for a function name or what is the deal with that?

Community
  • 1
  • 1
Patrick
  • 989
  • 3
  • 16
  • 23
  • It's using a decorator. Please post the implementation of the `fake` function, also include what is below that line. – phant0m Dec 13 '12 at 10:10
  • 1
    See [Understanding Python decorators](http://stackoverflow.com/questions/739654/understanding-python-decorators) and the tutorial note on [lambda forms](http://docs.python.org/2/tutorial/controlflow.html#lambda-forms). – Lev Levitsky Dec 13 '12 at 10:24
  • 1
    I assume the second line in `fake` ends with three quotes? If not, what you pasted is incomplete. – phant0m Dec 13 '12 at 10:24
  • 1
    You have two separate questions here. I think you will find that each has been asked many times before (though "decorator" is not an obvious search term if you don't know what the feature is called). – tripleee Dec 13 '12 at 10:26
  • One part that was never highlighted in this answer or the supposingly duplicate one, is how a Java custom annotation can be used as a direct correlation for Python Decorators. I vote, to reopen – Abhijit Dec 13 '12 at 10:31
  • 1
    @Abhijit It’s not possible. Python decorators are exactly that: decorators. They replace the decorated function by something else that is compatible to it. On the other hand, annotations are just some kind of meta-information you can attach to things. – poke Dec 13 '12 at 10:37

2 Answers2

5

First of all, @fake is a decorator.

What @fake appears to do is to conditionally replace the function that follows, i.e. split, with the lambda function (note how the two take the same parameters).

The decision is based on the FUNC_FAKE environment variable. If the latter equals * or contains split as one of its tokens, the replacement is made. Otherwise, it isn't.

The fact that the replacement is a lambda function is not important. It could have just as easily been made into a normal function:

def split_replacement(s, t, n):
   return [(s.field(i+1), s) for i in range(n)])

@fake(split_replacement)
def split(s, t, n):
   ...

This whole construct is rather baffling. I struggle to come up with a reason for doing things this way, other than to try and confuse other programmers (or to play with decorators).

Community
  • 1
  • 1
NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • You could even do `@fake` `def fake_split_replacement(...):` ... and then use this "simply-decorated" function as a decorator itself: `@fake_split_replacement` `def split(...):`, if you need it at several places. – glglgl Dec 13 '12 at 10:37
  • BTW, I disagree. This construct seems quite helpful to me, and I don't see a problem here... – glglgl Dec 13 '12 at 10:38
4

The first question is answered elsewhere.

For your second question:

x = lambda a, b, *args, **kwargs: <expression>

is just a shorthand for

def x(a, b, *args, **kwargs):
    return <expression>

See also here.

Community
  • 1
  • 1
glglgl
  • 89,107
  • 13
  • 149
  • 217
  • Could you PLEASE refrain from downvoting while I am still writing?! – glglgl Dec 13 '12 at 10:28
  • “Answer on lambda (I am writing)” – Why don’t you just click save once (and only once) you have actually written something useful? – poke Dec 13 '12 at 10:29
  • 1
    @poke I wanted to remain able to provide something useful before the question was closed... there were already 4 close votes. – glglgl Dec 13 '12 at 10:29